|
| 1 | +import { Client, MessageEmbed } from "discord.js"; |
| 2 | + |
| 3 | +import chalk from "chalk"; |
| 4 | +import { ICommand } from "wokcommands"; |
| 5 | +import { classModel } from "../../models/classModel"; |
| 6 | +import { |
| 7 | + checkForChannel, |
| 8 | + cleanChannelString, |
| 9 | + createTextChannel, |
| 10 | + findCategory, |
| 11 | + moveChannel, |
| 12 | + concatCategoryName, |
| 13 | +} from "../../utils/channelUtils"; |
| 14 | + |
| 15 | +function create_default_embed( |
| 16 | + client: Client, |
| 17 | + title: string, |
| 18 | + description: string |
| 19 | +) { |
| 20 | + const color = "#0099ff"; |
| 21 | + const thumbnail = |
| 22 | + "https://playantares.com/resources/CSSC-bot/cssc-server-icon.png"; |
| 23 | + const footer = `Delivered in: ${client.ws.ping}ms | CSSC-bot | ${process.env.VERSION}`; |
| 24 | + const footerIcon = "https://playantares.com/resources/CSSC-bot/icon.jpg"; |
| 25 | + |
| 26 | + // Embed construction |
| 27 | + const embed = new MessageEmbed() |
| 28 | + .setColor(color) |
| 29 | + .setTitle(title) |
| 30 | + .setThumbnail(thumbnail) |
| 31 | + .setDescription(description) |
| 32 | + .setFooter({ text: footer, iconURL: footerIcon }); |
| 33 | + return embed; |
| 34 | +} |
| 35 | + |
| 36 | +function cleanRoleString(role_name: string): string { |
| 37 | + const clean_role_name: string = role_name |
| 38 | + .toLowerCase() |
| 39 | + .replace(/[`~!@#$%^&*))|+=?;:'",.<>\{\}\[\]\\\/]/gi, "") |
| 40 | + .replace(/[ (]/gi, "-"); |
| 41 | + return clean_role_name; |
| 42 | +} |
| 43 | + |
| 44 | +export default { |
| 45 | + name: "csCreateChannels", |
| 46 | + category: "owner", |
| 47 | + description: "Update CS class channels", |
| 48 | + slash: true, |
| 49 | + testOnly: false, |
| 50 | + guildOnly: true, |
| 51 | + requiredPermissions: ["MANAGE_GUILD", "MANAGE_ROLES"], |
| 52 | + ownerOnly: true, |
| 53 | + |
| 54 | + callback: async ({ client, interaction: msgInt }) => { |
| 55 | + if (msgInt.guild === null) { |
| 56 | + console.log(chalk.red("No guild")); |
| 57 | + return; |
| 58 | + } |
| 59 | + |
| 60 | + await msgInt.deferReply({ ephemeral: true }); |
| 61 | + |
| 62 | + const courses = await classModel.find({}).sort({ CODE: 1 }); |
| 63 | + |
| 64 | + //create an array of the courses with cleaned names |
| 65 | + const cleaned_courses: string[] = []; |
| 66 | + for (let index = 0; index < courses.length; index++) { |
| 67 | + cleaned_courses.push(cleanChannelString(courses[index].CODE)); |
| 68 | + } |
| 69 | + |
| 70 | + // for (let index = 0; index < courses.length; index++) { |
| 71 | + // console.log(courses[index].CODE); |
| 72 | + // } |
| 73 | + |
| 74 | + const category_name = "COMP SCI CLASSES"; |
| 75 | + let category_number = 0; |
| 76 | + const max_category_size = 50; |
| 77 | + |
| 78 | + const cs_past_category_name = "PAST CLASSES"; |
| 79 | + let new_channel_count = 0; |
| 80 | + let move_channel_count = 0; |
| 81 | + |
| 82 | + console.log( |
| 83 | + `category name: ${concatCategoryName(category_name, category_number)}` |
| 84 | + ); |
| 85 | + //Move classes no longer in the db to cs_past_category_name |
| 86 | + let cs_category = checkForChannel( |
| 87 | + msgInt.guild, |
| 88 | + concatCategoryName(category_name, category_number) |
| 89 | + ); |
| 90 | + console.log(`Channel: ${cs_category}`); |
| 91 | + |
| 92 | + while (cs_category != undefined && cs_category.type == "GUILD_CATEGORY") { |
| 93 | + const children = Array.from(cs_category.children.values()); |
| 94 | + for (let index = 0; index < children.length; index++) { |
| 95 | + const match = cleaned_courses.find((course) => { |
| 96 | + return course == children[index].name; |
| 97 | + }); |
| 98 | + if (match != undefined) { |
| 99 | + continue; |
| 100 | + } |
| 101 | + console.log(`Moving: ${children[index]} to: ${cs_past_category_name}`); |
| 102 | + await moveChannel(msgInt.guild, children[index], cs_past_category_name); |
| 103 | + } |
| 104 | + |
| 105 | + ++category_number; |
| 106 | + cs_category = checkForChannel( |
| 107 | + msgInt.guild, |
| 108 | + concatCategoryName(category_name, category_number) |
| 109 | + ); |
| 110 | + } |
| 111 | + category_number = 0; |
| 112 | + |
| 113 | + for (let index = 0; index < courses.length; index++) { |
| 114 | + // Iterate through courses in db |
| 115 | + const channel = checkForChannel( |
| 116 | + msgInt.guild, |
| 117 | + cleanChannelString(courses[index].CODE) |
| 118 | + ); |
| 119 | + |
| 120 | + let category = await ( |
| 121 | + await findCategory( |
| 122 | + msgInt.guild, |
| 123 | + concatCategoryName(category_name, category_number) |
| 124 | + ) |
| 125 | + ).fetch(true); |
| 126 | + |
| 127 | + // Increment category if category is full |
| 128 | + if (category.children.size >= max_category_size - 1) { |
| 129 | + ++category_number; |
| 130 | + category = await ( |
| 131 | + await findCategory( |
| 132 | + msgInt.guild, |
| 133 | + concatCategoryName(category_name, category_number) |
| 134 | + ) |
| 135 | + ).fetch(true); |
| 136 | + console.log( |
| 137 | + `old category full, new category: ${concatCategoryName( |
| 138 | + category_name, |
| 139 | + category_number |
| 140 | + )} created` |
| 141 | + ); |
| 142 | + } |
| 143 | + console.log( |
| 144 | + `Working in category: ${concatCategoryName( |
| 145 | + category_name, |
| 146 | + category_number |
| 147 | + )} size: ${category.children.size}` |
| 148 | + ); |
| 149 | + |
| 150 | + // Create new channels |
| 151 | + if (channel === undefined || channel.type !== "GUILD_TEXT") { |
| 152 | + const new_channel = await createTextChannel( |
| 153 | + msgInt.guild, |
| 154 | + cleanChannelString(courses[index].CODE), |
| 155 | + courses[index].INFO, |
| 156 | + category |
| 157 | + ); |
| 158 | + |
| 159 | + ++new_channel_count; |
| 160 | + console.log(chalk.yellow(`Created channel: ${new_channel.name}`)); |
| 161 | + |
| 162 | + courses[index].CHANNEL_ID = new_channel.id; |
| 163 | + courses[index].save(); |
| 164 | + |
| 165 | + // Ping members who have this role |
| 166 | + const role = msgInt.guild.roles.cache.find((role) => { |
| 167 | + return ( |
| 168 | + cleanRoleString(role.name) == |
| 169 | + cleanChannelString(courses[index].CODE) |
| 170 | + ); |
| 171 | + }); |
| 172 | + if (role !== undefined) { |
| 173 | + //Ping member |
| 174 | + new_channel.send(`Hey! <@&${role.id}> here is a channel for you!`); |
| 175 | + } |
| 176 | + } else if ( |
| 177 | + channel.parent !== null && |
| 178 | + !channel.parent.name.startsWith(category_name) |
| 179 | + ) { |
| 180 | + // Moves and updates old channels |
| 181 | + console.log( |
| 182 | + `Moving: ${channel.name} to: ${concatCategoryName( |
| 183 | + category_name, |
| 184 | + category_number |
| 185 | + )}` |
| 186 | + ); |
| 187 | + channel.edit({ topic: courses[index].INFO }); |
| 188 | + move_channel_count += await moveChannel( |
| 189 | + msgInt.guild, |
| 190 | + channel, |
| 191 | + concatCategoryName(category_name, category_number) |
| 192 | + ); |
| 193 | + |
| 194 | + courses[index].CHANNEL_ID = channel.id; |
| 195 | + courses[index].save(); |
| 196 | + // Ping members who have this role |
| 197 | + const role = msgInt.guild.roles.cache.find((role) => { |
| 198 | + return ( |
| 199 | + cleanRoleString(role.name) == |
| 200 | + cleanChannelString(courses[index].CODE) |
| 201 | + ); |
| 202 | + }); |
| 203 | + if (role !== undefined) { |
| 204 | + //Ping member |
| 205 | + channel.send(`Hey! <@&${role.id}> here is the channel for you!`); |
| 206 | + } |
| 207 | + } else if ( |
| 208 | + channel.parent !== null && |
| 209 | + channel.parent.name.startsWith(category_name) |
| 210 | + ) { |
| 211 | + // updates old channels |
| 212 | + channel.edit({ topic: courses[index].INFO }); |
| 213 | + } |
| 214 | + } |
| 215 | + |
| 216 | + const title = "Create Classes"; |
| 217 | + let description = `Created ${new_channel_count} new channels\nMoved ${move_channel_count} channels`; |
| 218 | + if (move_channel_count > 0) { |
| 219 | + description += ` to ${concatCategoryName( |
| 220 | + category_name, |
| 221 | + category_number |
| 222 | + )}`; |
| 223 | + } |
| 224 | + |
| 225 | + const embed = create_default_embed(client, title, description); |
| 226 | + await msgInt.editReply({ embeds: [embed] }); |
| 227 | + |
| 228 | + console.log(chalk.yellow(description)); |
| 229 | + |
| 230 | + // Log the command usage |
| 231 | + console.log( |
| 232 | + chalk.blue( |
| 233 | + `${chalk.green(`[COMMAND]`)} ${chalk.yellow( |
| 234 | + msgInt.user.tag |
| 235 | + )} used the ${chalk.green( |
| 236 | + `/csCreateChannels` |
| 237 | + )} command in ${chalk.yellow(msgInt.guild?.name)}` |
| 238 | + ) |
| 239 | + ); |
| 240 | + }, |
| 241 | +} as ICommand; |
0 commit comments