Skip to content

Feature/schiltz3/create channels #39

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 35 commits into from
Sep 12, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
c93c16c
WIP
schiltz3 Sep 7, 2022
bf6395e
Merge branch 'staging' into feature/schiltz3/create-channels
schiltz3 Sep 7, 2022
8fc0485
WIP
schiltz3 Sep 8, 2022
0dda507
Merge branch 'staging' into feature/schiltz3/create-channels
schiltz3 Sep 8, 2022
952015a
WIP
schiltz3 Sep 8, 2022
1ddc599
Create channels rework
schiltz3 Sep 8, 2022
b102371
Apply auto formatting changes
schiltz3 Sep 8, 2022
ab67099
Archive old classes
schiltz3 Sep 8, 2022
f9b8c62
Deepsource fixes
schiltz3 Sep 8, 2022
8e4669c
Add ability to pass in category or category name
schiltz3 Sep 9, 2022
f7e166b
split more than 50 channels into separate categories
schiltz3 Sep 9, 2022
60e1daa
Clean up createTextChannel
schiltz3 Sep 9, 2022
068deba
Further clean up for createTextChannel
schiltz3 Sep 9, 2022
178acab
Deepsource
schiltz3 Sep 9, 2022
31e1d5f
Fixed issue where you could move a channel into a full category
schiltz3 Sep 9, 2022
be7fcdf
Prevent excessive moving
schiltz3 Sep 9, 2022
b4071fa
Clean strings in functions that need it
schiltz3 Sep 9, 2022
38c2a8d
Deepsource
schiltz3 Sep 9, 2022
ca6e279
Apply auto formatting changes
schiltz3 Sep 9, 2022
57d4e88
deepsource
schiltz3 Sep 9, 2022
74d1234
Change string cleaning
schiltz3 Sep 10, 2022
3395191
Only clean channel strings
schiltz3 Sep 10, 2022
cfcc963
WIP: Moving old channels not working
schiltz3 Sep 10, 2022
8cd44ed
Refresh cache, and lower max number of channels by 1
schiltz3 Sep 11, 2022
6529905
Update cleanString
schiltz3 Sep 11, 2022
27ab197
Change cleaned_courses data structure
schiltz3 Sep 11, 2022
b198737
Update existing channel descriptions
schiltz3 Sep 11, 2022
5b3a174
Ping members
schiltz3 Sep 11, 2022
3e34c37
Ping roles if you move the course from past courses
schiltz3 Sep 11, 2022
4580aa4
Merge branch 'staging' into feature/schiltz3/create-channels
schiltz3 Sep 11, 2022
13564ba
Remove delete command
schiltz3 Sep 12, 2022
7d728e2
Remove unused code
schiltz3 Sep 12, 2022
df4e247
Deepsource
schiltz3 Sep 12, 2022
4efe07b
Deepsource
schiltz3 Sep 12, 2022
4afa13d
Deepsource
schiltz3 Sep 12, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
241 changes: 241 additions & 0 deletions commands/owner/csCreateChannels.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,241 @@
import { Client, MessageEmbed } from "discord.js";

import chalk from "chalk";
import { ICommand } from "wokcommands";
import { classModel } from "../../models/classModel";
import {
checkForChannel,
cleanChannelString,
createTextChannel,
findCategory,
moveChannel,
concatCategoryName,
} from "../../utils/channelUtils";

function create_default_embed(
client: Client,
title: string,
description: string
) {
const color = "#0099ff";
const thumbnail =
"https://playantares.com/resources/CSSC-bot/cssc-server-icon.png";
const footer = `Delivered in: ${client.ws.ping}ms | CSSC-bot | ${process.env.VERSION}`;
const footerIcon = "https://playantares.com/resources/CSSC-bot/icon.jpg";

// Embed construction
const embed = new MessageEmbed()
.setColor(color)
.setTitle(title)
.setThumbnail(thumbnail)
.setDescription(description)
.setFooter({ text: footer, iconURL: footerIcon });
return embed;
}

function cleanRoleString(role_name: string): string {
const clean_role_name: string = role_name
.toLowerCase()
.replace(/[`~!@#$%^&*))|+=?;:'",.<>\{\}\[\]\\\/]/gi, "")
.replace(/[ (]/gi, "-");
return clean_role_name;
}

export default {
name: "csCreateChannels",
category: "owner",
description: "Update CS class channels",
slash: true,
testOnly: false,
guildOnly: true,
requiredPermissions: ["MANAGE_GUILD", "MANAGE_ROLES"],
ownerOnly: true,

callback: async ({ client, interaction: msgInt }) => {
if (msgInt.guild === null) {
console.log(chalk.red("No guild"));
return;
}

await msgInt.deferReply({ ephemeral: true });

const courses = await classModel.find({}).sort({ CODE: 1 });

//create an array of the courses with cleaned names
const cleaned_courses: string[] = [];
for (let index = 0; index < courses.length; index++) {
cleaned_courses.push(cleanChannelString(courses[index].CODE));
}

// for (let index = 0; index < courses.length; index++) {
// console.log(courses[index].CODE);
// }

const category_name = "COMP SCI CLASSES";
let category_number = 0;
const max_category_size = 50;

const cs_past_category_name = "PAST CLASSES";
let new_channel_count = 0;
let move_channel_count = 0;

console.log(
`category name: ${concatCategoryName(category_name, category_number)}`
);
//Move classes no longer in the db to cs_past_category_name
let cs_category = checkForChannel(
msgInt.guild,
concatCategoryName(category_name, category_number)
);
console.log(`Channel: ${cs_category}`);

while (cs_category != undefined && cs_category.type == "GUILD_CATEGORY") {
const children = Array.from(cs_category.children.values());
for (let index = 0; index < children.length; index++) {
const match = cleaned_courses.find((course) => {
return course == children[index].name;
});
if (match != undefined) {
continue;
}
console.log(`Moving: ${children[index]} to: ${cs_past_category_name}`);
await moveChannel(msgInt.guild, children[index], cs_past_category_name);
}

++category_number;
cs_category = checkForChannel(
msgInt.guild,
concatCategoryName(category_name, category_number)
);
}
category_number = 0;

for (let index = 0; index < courses.length; index++) {
// Iterate through courses in db
const channel = checkForChannel(
msgInt.guild,
cleanChannelString(courses[index].CODE)
);

let category = await (
await findCategory(
msgInt.guild,
concatCategoryName(category_name, category_number)
)
).fetch(true);

// Increment category if category is full
if (category.children.size >= max_category_size - 1) {
++category_number;
category = await (
await findCategory(
msgInt.guild,
concatCategoryName(category_name, category_number)
)
).fetch(true);
console.log(
`old category full, new category: ${concatCategoryName(
category_name,
category_number
)} created`
);
}
console.log(
`Working in category: ${concatCategoryName(
category_name,
category_number
)} size: ${category.children.size}`
);

// Create new channels
if (channel === undefined || channel.type !== "GUILD_TEXT") {
const new_channel = await createTextChannel(
msgInt.guild,
cleanChannelString(courses[index].CODE),
courses[index].INFO,
category
);

++new_channel_count;
console.log(chalk.yellow(`Created channel: ${new_channel.name}`));

courses[index].CHANNEL_ID = new_channel.id;
courses[index].save();

// Ping members who have this role
const role = msgInt.guild.roles.cache.find((role) => {
return (
cleanRoleString(role.name) ==
cleanChannelString(courses[index].CODE)
);
});
if (role !== undefined) {
//Ping member
new_channel.send(`Hey! <@&${role.id}> here is a channel for you!`);
}
} else if (
channel.parent !== null &&
!channel.parent.name.startsWith(category_name)
) {
// Moves and updates old channels
console.log(
`Moving: ${channel.name} to: ${concatCategoryName(
category_name,
category_number
)}`
);
channel.edit({ topic: courses[index].INFO });
move_channel_count += await moveChannel(
msgInt.guild,
channel,
concatCategoryName(category_name, category_number)
);

courses[index].CHANNEL_ID = channel.id;
courses[index].save();
// Ping members who have this role
const role = msgInt.guild.roles.cache.find((role) => {
return (
cleanRoleString(role.name) ==
cleanChannelString(courses[index].CODE)
);
});
if (role !== undefined) {
//Ping member
channel.send(`Hey! <@&${role.id}> here is the channel for you!`);
}
} else if (
channel.parent !== null &&
channel.parent.name.startsWith(category_name)
) {
// updates old channels
channel.edit({ topic: courses[index].INFO });
}
}

const title = "Create Classes";
let description = `Created ${new_channel_count} new channels\nMoved ${move_channel_count} channels`;
if (move_channel_count > 0) {
description += ` to ${concatCategoryName(
category_name,
category_number
)}`;
}

const embed = create_default_embed(client, title, description);
await msgInt.editReply({ embeds: [embed] });

console.log(chalk.yellow(description));

// Log the command usage
console.log(
chalk.blue(
`${chalk.green(`[COMMAND]`)} ${chalk.yellow(
msgInt.user.tag
)} used the ${chalk.green(
`/csCreateChannels`
)} command in ${chalk.yellow(msgInt.guild?.name)}`
)
);
},
} as ICommand;
87 changes: 87 additions & 0 deletions utils/channelUtils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
import { CategoryChannel, Guild, GuildChannel } from "discord.js";
import chalk from "chalk";

export function cleanChannelString(s: string): string {
return s
.toLowerCase()
.replace(/[`~!@#$%^&*))|+=?;:'",.<>\{\}\[\]\\\/]/gi, "")
.replace("compsci ", "cs")
.replace(/[ (]/gi, "-");
}

export function checkForChannel(guild: Guild, channel_name: string) {
return guild.channels.cache.find((channel) => {
return channel.name == channel_name;
});
}

export async function findCategory(guild: Guild, category_name: string) {
let category = guild.channels.cache.find((category) => {
return category.name == category_name;
});

if (category === undefined || category.type !== "GUILD_CATEGORY") {
category = await guild.channels.create(category_name, {
type: "GUILD_CATEGORY",
});
}

return category;
}
export async function createTextChannel(
guild: Guild,
name: string,
topic: string,
category?: CategoryChannel,
category_name?: string
) {
//Determine which arg to use
let channel_parent: CategoryChannel | undefined;
if (category !== undefined) {
channel_parent = category;
} else if (category_name !== undefined) {
channel_parent = await findCategory(guild, category_name);
} else {
throw Error(
"Must specify either channel_category or channel_category_name"
);
}

return guild.channels.create(cleanChannelString(name), {
type: "GUILD_TEXT",
topic: topic,
parent: channel_parent,
});
}

export async function moveChannel(
guild: Guild,
channel: GuildChannel,
category_name: string
): Promise<number> {
if (
channel.parent === null ||
channel.parent === undefined ||
channel.parent?.name != category_name
) {
const category = await findCategory(guild, category_name);
channel.setParent(category);

console.log(
chalk.yellow(
`Moved channel ${channel.name} from: ${channel.parent?.name} to: ${category_name}`
)
);
return 1;
}
return 0;
}

export function concatCategoryName(
category_name: string,
category_number: number
) {
return category_number == 0
? category_name
: `${category_name} ${category_number}`;
}