Merge branch 'master' into 'brs'
BRS Quorum Fixes See merge request engineering/communityrelations!24merge-requests/24/merge
commit
4c23bdffc3
|
@ -41,7 +41,8 @@
|
|||
"keyword-spacing": "off",
|
||||
"no-multiple-empty-lines": "off",
|
||||
"consistent-return": "off",
|
||||
"no-continue": "off"
|
||||
"no-continue": "off",
|
||||
"no-plusplus": "off"
|
||||
},
|
||||
"ignorePatterns": "**/*.js"
|
||||
}
|
||||
|
|
|
@ -349,6 +349,13 @@ export default class Root extends Route {
|
|||
oID: id,
|
||||
processed: false,
|
||||
msg: msg.id,
|
||||
results: {
|
||||
yea: 0,
|
||||
nay: 0,
|
||||
present: 0,
|
||||
absent: 0,
|
||||
},
|
||||
votedDirectors: [],
|
||||
});
|
||||
|
||||
res.status(200).json({
|
||||
|
@ -961,8 +968,8 @@ export default class Root extends Route {
|
|||
confirmationEmbed.addField('Results', `**Total:** ${total.length}\n**Yea:** ${yea}\n**Nay:** ${nay}\n**Present:** ${present}\n**Absent:** ${absent}`);
|
||||
await this.directorLogs.createMessage({ embed: confirmationEmbed });
|
||||
|
||||
const excludingYea = nay + present + absent;
|
||||
if (yea > excludingYea) {
|
||||
const totalDirectors = yea + nay + present + absent;
|
||||
if (yea / totalDirectors >= 0.6) {
|
||||
const resolutionEmbed = this.genEmbed(
|
||||
motion.oID,
|
||||
'res',
|
||||
|
|
|
@ -14,7 +14,6 @@ import {
|
|||
Merchant, MerchantInterface,
|
||||
Moderation, ModerationInterface,
|
||||
Motion, MotionInterface,
|
||||
NNTrainingData, NNTrainingDataInterface,
|
||||
Note, NoteInterface,
|
||||
PagerNumber, PagerNumberInterface,
|
||||
Proclamation, ProclamationInterface,
|
||||
|
@ -48,7 +47,7 @@ export default class Client extends eris.Client {
|
|||
|
||||
public stripe: Stripe;
|
||||
|
||||
public db: { Customer: mongoose.Model<CustomerInterface>, CustomerPortal: mongoose.Model<CustomerPortalInterface>, ExecutiveOrder: mongoose.Model<ExecutiveOrderInterface>, File: mongoose.Model<FileInterface>, Inquiry: mongoose.Model<InquiryInterface>, Member: mongoose.Model<MemberInterface>, Merchant: mongoose.Model<MerchantInterface>, Moderation: mongoose.Model<ModerationInterface>, Motion: mongoose.Model<MotionInterface>, NNTrainingData: mongoose.Model<NNTrainingDataInterface>, Note: mongoose.Model<NoteInterface>, PagerNumber: mongoose.Model<PagerNumberInterface>, Proclamation: mongoose.Model<ProclamationInterface>, Promo: mongoose.Model<PromoInterface>, Rank: mongoose.Model<RankInterface>, Redirect: mongoose.Model<RedirectInterface>, Resolution: mongoose.Model<ResolutionInterface>, Score: mongoose.Model<ScoreInterface>, ScoreHistorical: mongoose.Model<ScoreHistoricalInterface>, Staff: mongoose.Model<StaffInterface>, Stat: mongoose.Model<StatInterface>, local: { muted: LocalStorage } };
|
||||
public db: { Customer: mongoose.Model<CustomerInterface>, CustomerPortal: mongoose.Model<CustomerPortalInterface>, ExecutiveOrder: mongoose.Model<ExecutiveOrderInterface>, File: mongoose.Model<FileInterface>, Inquiry: mongoose.Model<InquiryInterface>, Member: mongoose.Model<MemberInterface>, Merchant: mongoose.Model<MerchantInterface>, Moderation: mongoose.Model<ModerationInterface>, Motion: mongoose.Model<MotionInterface>, Note: mongoose.Model<NoteInterface>, PagerNumber: mongoose.Model<PagerNumberInterface>, Proclamation: mongoose.Model<ProclamationInterface>, Promo: mongoose.Model<PromoInterface>, Rank: mongoose.Model<RankInterface>, Redirect: mongoose.Model<RedirectInterface>, Resolution: mongoose.Model<ResolutionInterface>, Score: mongoose.Model<ScoreInterface>, ScoreHistorical: mongoose.Model<ScoreHistoricalInterface>, Staff: mongoose.Model<StaffInterface>, Stat: mongoose.Model<StatInterface>, local: { muted: LocalStorage } };
|
||||
|
||||
constructor(token: string, options?: eris.ClientOptions) {
|
||||
super(token, options);
|
||||
|
@ -56,7 +55,7 @@ export default class Client extends eris.Client {
|
|||
this.events = new Collection<Event>();
|
||||
this.intervals = new Collection<NodeJS.Timeout>();
|
||||
this.queue = new Queue(this);
|
||||
this.db = { Customer, CustomerPortal, ExecutiveOrder, File, Inquiry, Member, Merchant, Moderation, Motion, NNTrainingData, Note, PagerNumber, Promo, Proclamation, Rank, Redirect, Resolution, Score, ScoreHistorical, Staff, Stat, local: { muted: new LocalStorage('muted') } };
|
||||
this.db = { Customer, CustomerPortal, ExecutiveOrder, File, Inquiry, Member, Merchant, Moderation, Motion, Note, PagerNumber, Promo, Proclamation, Rank, Redirect, Resolution, Score, ScoreHistorical, Staff, Stat, local: { muted: new LocalStorage('muted') } };
|
||||
}
|
||||
|
||||
get report() {
|
||||
|
|
|
@ -6,7 +6,7 @@ export default class AddRedirect extends Command {
|
|||
super(client);
|
||||
this.name = 'addredirect';
|
||||
this.description = 'Adds a redirect link for \'loc.sh\'';
|
||||
this.usage = 'addredirect <redirect to url> <key>';
|
||||
this.usage = `${this.client.config.prefix}addredirect <redirect to url> <key>`;
|
||||
this.aliases = ['ar'];
|
||||
this.permissions = 6;
|
||||
this.enabled = true;
|
||||
|
|
|
@ -10,7 +10,7 @@ export default class Profile extends Command {
|
|||
super(client);
|
||||
this.name = 'profile';
|
||||
this.description = 'Manages your profile on CR.';
|
||||
this.usage = 'profile <bio/github/gitlab> <new value>\n*Provide no value in subcommand to clear data.*';
|
||||
this.usage = `${this.client.config.prefix}profile <bio/github/gitlab> <new value>\n*Provide no value in subcommand to clear data.*`;
|
||||
this.permissions = 0;
|
||||
this.enabled = true;
|
||||
this.subcmds = [Profile_Bio, Profile_GitHub, Profile_Gitlab];
|
||||
|
|
|
@ -6,7 +6,7 @@ export default class Profile_Bio extends Command {
|
|||
super(client);
|
||||
this.name = 'bio';
|
||||
this.description = 'Updates your bio on your profile.';
|
||||
this.usage = `${this.client.config.prefix}bio <new bio>`;
|
||||
this.usage = `${this.client.config.prefix}profile bio <new bio>`;
|
||||
this.permissions = 0;
|
||||
this.enabled = true;
|
||||
}
|
||||
|
|
|
@ -6,7 +6,7 @@ export default class Profile_GitHub extends Command {
|
|||
super(client);
|
||||
this.name = 'github';
|
||||
this.description = 'Updates your GitHub information on your profile.';
|
||||
this.usage = `${this.client.config.prefix}github <GitHub profile URL>`;
|
||||
this.usage = `${this.client.config.prefix}profile github <GitHub profile URL>`;
|
||||
this.permissions = 0;
|
||||
this.enabled = true;
|
||||
}
|
||||
|
|
|
@ -6,7 +6,7 @@ export default class Profile_GitLab extends Command {
|
|||
super(client);
|
||||
this.name = 'gitlab';
|
||||
this.description = 'Updates your GitLab information on your profile.';
|
||||
this.usage = `${this.client.config.prefix}gitlab <GitLab profile URL>`;
|
||||
this.usage = `${this.client.config.prefix}profile gitlab <GitLab profile URL>`;
|
||||
this.permissions = 0;
|
||||
this.enabled = true;
|
||||
}
|
||||
|
|
|
@ -27,7 +27,7 @@ export default class Score_Hist extends Command {
|
|||
if (!args[0] || !this.checkCustomPermissions(this.client.util.resolveMember(message.author.id, this.mainGuild), 4)) {
|
||||
user = message.author;
|
||||
if (!user) return this.error(message.channel, 'Member not found.');
|
||||
const hists = await this.client.db.ScoreHistorical.find({ userID: user.id }).lean().exec();
|
||||
const hists = await this.client.db.ScoreHistorical.find({ userID: user.id }).limit(31).lean().exec();
|
||||
if (!hists) return this.error(message.channel, 'No history found.');
|
||||
if (hists.length < 1) return this.error(message.channel, 'No history found.');
|
||||
const histArray: [{ name: string, value: string }?] = [];
|
||||
|
@ -177,7 +177,7 @@ export default class Score_Hist extends Command {
|
|||
user = this.client.util.resolveMember(sc.userID, this.mainGuild)?.user;
|
||||
}
|
||||
if (!user) return this.error(message.channel, 'Member not found.');
|
||||
const hists = await this.client.db.ScoreHistorical.find({ userID: user.id }).lean().exec();
|
||||
const hists = await this.client.db.ScoreHistorical.find({ userID: user.id }).limit(31).lean().exec();
|
||||
if (!hists) return this.error(message.channel, 'No history found.');
|
||||
if (hists.length < 1) return this.error(message.channel, 'No history found.');
|
||||
const histArray: [{ name: string, value: string }?] = [];
|
||||
|
|
|
@ -5,8 +5,8 @@ export default class Setnick extends Command {
|
|||
constructor(client: Client) {
|
||||
super(client);
|
||||
this.name = 'setnick';
|
||||
this.description = 'Changes the nickname of a member';
|
||||
this.usage = 'setnick <member> [new nickname]';
|
||||
this.description = 'Changes the nickname of a member.';
|
||||
this.usage = `${this.client.config.prefix}setnick <member> [new nickname]`;
|
||||
this.permissions = 2;
|
||||
this.guildOnly = true;
|
||||
this.enabled = true;
|
||||
|
|
|
@ -1,15 +1,6 @@
|
|||
<<<<<<< HEAD
|
||||
{
|
||||
"moderation": {
|
||||
"modlogs": "446080867065135115",
|
||||
"automod": ""
|
||||
}
|
||||
}
|
||||
=======
|
||||
{
|
||||
"moderation": {
|
||||
"modlogs": "446080867065135115",
|
||||
"automod": ""
|
||||
}
|
||||
}
|
||||
>>>>>>> Hiroyuki/communityrelations-master
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
<<<<<<< HEAD
|
||||
{
|
||||
"whois": {
|
||||
"titleAndDepartment": "<:loc:607695848612167700>",
|
||||
|
@ -13,19 +12,3 @@
|
|||
"error": "<:modError:578750737920688128>"
|
||||
}
|
||||
}
|
||||
=======
|
||||
{
|
||||
"whois": {
|
||||
"titleAndDepartment": "<:loc:607695848612167700>",
|
||||
"email": "<:email:699786452267040878>",
|
||||
"gitlab": "<:gitlab:699788655748841492>",
|
||||
"github": "<:github:699786469404835939>",
|
||||
"bio": "<:bio:699786408193294416>"
|
||||
},
|
||||
"statusMessages": {
|
||||
"success": "<:modSuccess:578750988907970567>",
|
||||
"loading": "<a:modloading:588607353935364106>",
|
||||
"error": "<:modError:578750737920688128>"
|
||||
}
|
||||
}
|
||||
>>>>>>> Hiroyuki/communityrelations-master
|
||||
|
|
|
@ -1,29 +0,0 @@
|
|||
/* eslint-disable no-unreachable */
|
||||
import { Message } from 'eris';
|
||||
import { Client, Event, LocalStorage } from '../class';
|
||||
|
||||
export default class Training extends Event {
|
||||
public client: Client;
|
||||
|
||||
public storage: LocalStorage;
|
||||
|
||||
constructor(client: Client) {
|
||||
super(client);
|
||||
this.event = 'messageCreate';
|
||||
this.storage = new LocalStorage('training');
|
||||
}
|
||||
|
||||
public async run(message: Message) {
|
||||
return;
|
||||
try {
|
||||
if (message.channel.id !== '485680288123584525') return;
|
||||
await this.storage.set(message.id, {
|
||||
content: message.content,
|
||||
date: new Date(),
|
||||
score: -1,
|
||||
});
|
||||
} catch (err) {
|
||||
this.client.util.handleError(err, message);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -3,4 +3,3 @@ export { default as CommandHandler } from './CommandHandler';
|
|||
export { default as guildMemberAdd } from './guildMemberAdd';
|
||||
export { default as messageReactionAdd } from './messageReactionAdd';
|
||||
export { default as ready } from './ready';
|
||||
export { default as Training } from './Training';
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import { Emoji, GuildTextableChannel, Member, Message } from 'eris';
|
||||
import { Client, Event } from '../class';
|
||||
import { Client, Event, RichEmbed } from '../class';
|
||||
|
||||
export default class MessageReactionAdd extends Event {
|
||||
public client: Client;
|
||||
|
@ -17,8 +17,11 @@ export default class MessageReactionAdd extends Event {
|
|||
private directorRole: string;
|
||||
|
||||
|
||||
public async run(message: Message<GuildTextableChannel>, _emoji: Emoji, reactor: Member) {
|
||||
public async run(message: Message<GuildTextableChannel>, emoji: Emoji, reactor: Member) {
|
||||
if (message.channel.id !== this.directorLogs) return;
|
||||
if (!(message instanceof Message)) {
|
||||
message = <Message<GuildTextableChannel>>(await (message as Message).channel.getMessage((message as Message).id));
|
||||
}
|
||||
if (message.author.id !== this.client.user.id) return;
|
||||
|
||||
if (!reactor.roles[0]) {
|
||||
|
@ -28,46 +31,79 @@ export default class MessageReactionAdd extends Event {
|
|||
if (!reactor.roles.includes(this.directorRole)) return;
|
||||
|
||||
const proc = await this.client.db.Proclamation.findOne({ msg: message.id, processed: false });
|
||||
if (proc) {
|
||||
if (proc.votedDirectors?.includes(message.author.id)) return;
|
||||
|
||||
let yea = await message.getReaction('modSuccess:578750988907970567');
|
||||
yea = yea.filter((val) => !val.bot);
|
||||
let nay = await message.getReaction('modError:578750737920688128');
|
||||
nay = nay.filter((val) => !val.bot);
|
||||
let present = await message.getReaction('🙋');
|
||||
present = present.filter((val) => !val.bot);
|
||||
if (!proc?.votedDirectors.includes(reactor.id)) {
|
||||
let type: 'yea' | 'nay' | 'present';
|
||||
|
||||
const totalDirectors = message.channel.guild.members.filter((member) => member.roles.includes(this.directorRole)).length;
|
||||
if (emoji.id === '578750988907970567') type = 'yea';
|
||||
else if (emoji.id === '578750737920688128') type = 'nay';
|
||||
else if (emoji.name === '🙋') type = 'present';
|
||||
|
||||
const processed = totalDirectors === (yea.length + nay.length + present.length) || Date.now() - proc.at > 604800000;
|
||||
const absent = totalDirectors - (yea.length + nay.length + present.length);
|
||||
const votes = proc.results;
|
||||
|
||||
await proc.updateOne({
|
||||
results: {
|
||||
yea: yea.length,
|
||||
nay: nay.length,
|
||||
present: present.length,
|
||||
absent,
|
||||
},
|
||||
processed,
|
||||
votedDirectors: [...(proc.votedDirectors || []), message.author.id],
|
||||
});
|
||||
const inTheMajority = yea.length > nay.length + present.length;
|
||||
switch (type) {
|
||||
case 'yea':
|
||||
votes.yea++;
|
||||
await proc.updateOne({
|
||||
results: {
|
||||
...proc.results,
|
||||
yea: votes.yea,
|
||||
},
|
||||
votedDirectors: [...proc.votedDirectors, reactor.id],
|
||||
});
|
||||
break;
|
||||
|
||||
if (processed) {
|
||||
const author = this.client.users.get(proc.issuer) || await this.client.getRESTUser(proc.issuer);
|
||||
case 'nay':
|
||||
votes.nay++;
|
||||
await proc.updateOne({
|
||||
results: {
|
||||
...proc.results,
|
||||
nay: votes.nay,
|
||||
},
|
||||
votedDirectors: [...proc.votedDirectors, reactor.id],
|
||||
});
|
||||
break;
|
||||
|
||||
if (inTheMajority) {
|
||||
await author.createMessage(`__**Proclamation Majority Vote Received**__\nThe Proclamation you created at Library of Code sp-us, titled **${proc.subject}** (\`${proc.oID}\`) received the majority vote.`);
|
||||
await message.channel.createMessage(`__**Proclamation Results**__\nProclamation issued by ${author.mention} **received** the majority vote. Proclamation ID: ${proc.oID}\n\n__Results:__\n**Yea:** ${yea.length}\n**Nay:** ${nay.length}\n**Present:** ${present.length}\n**Absent:** ${absent}`);
|
||||
} else {
|
||||
await author.createMessage(`__**Proclamation Majority Vote Lost**__\nThe Proclamation you created at Library of Code sp-us, titled **${proc.subject}** (\`${proc.oID}\`) lost the majority vote.`);
|
||||
await message.channel.createMessage(`__**Proclamation Results**__\nProclamation issued by ${author.mention} **lost** the majority vote. Proclamation ID: ${proc.oID}\n\n__Results:__\n**Yea:** ${yea.length}\n**Nay:** ${nay.length}\n**Present:** ${present.length}\n**Absent:** ${absent}`);
|
||||
}
|
||||
case 'present':
|
||||
votes.present++;
|
||||
await proc.updateOne({
|
||||
results: {
|
||||
...proc.results,
|
||||
present: votes.present,
|
||||
},
|
||||
votedDirectors: [...proc.votedDirectors, reactor.id],
|
||||
});
|
||||
break;
|
||||
|
||||
default: return;
|
||||
}
|
||||
|
||||
reactor.user.createMessage(`__**Vote Recorded**__\nYour vote on the proclamation with ID \`${proc.id}\` at Library of Code sp-us was successfully recorded.`);
|
||||
const totalDirectors = message.channel.guild.members.filter((member) => member.roles.includes('662163685439045632'));
|
||||
|
||||
if (votes.yea / totalDirectors.length >= 0.6) {
|
||||
await proc.updateOne({
|
||||
processed: true,
|
||||
results: {
|
||||
...votes,
|
||||
absent: totalDirectors.length - (votes.present + votes.nay + votes.present),
|
||||
},
|
||||
});
|
||||
|
||||
await message.delete(`Proclamation with ID ${proc.oID} processed.`);
|
||||
|
||||
const embed = new RichEmbed();
|
||||
embed.setAuthor(message.embeds[0].author.name, message.embeds[0].author.icon_url);
|
||||
embed.setTitle('Proclamation');
|
||||
embed.setDescription(`${proc.oID}\n\n_This action is available on the Board Register System Directory. You can make changes or edit it [here](https://board.ins/repository)._\n\n__This proclamation was confirmed at ${new Date().toLocaleString()}.__`);
|
||||
embed.addField('Subject', proc.subject);
|
||||
embed.addField('Body', proc.body);
|
||||
embed.setColor(0x29b350);
|
||||
embed.setFooter('Library of Code sp-us | Board Register System', 'https://static.libraryofcode.org/library_of_code.png');
|
||||
embed.setTimestamp();
|
||||
|
||||
await message.channel.createMessage({ embed });
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,13 +0,0 @@
|
|||
import { Document, Schema, model } from 'mongoose';
|
||||
|
||||
export interface NNTrainingDataInterface extends Document {
|
||||
name: string,
|
||||
data: [{ input: any, output: object }];
|
||||
}
|
||||
|
||||
const NNTrainingData: Schema = new Schema({
|
||||
name: String,
|
||||
data: Array,
|
||||
});
|
||||
|
||||
export default model<NNTrainingDataInterface>('NNTrainingData', NNTrainingData);
|
|
@ -12,7 +12,6 @@ export interface ProclamationInterface extends Document {
|
|||
present: number;
|
||||
absent: number;
|
||||
};
|
||||
acceptedAt: number;
|
||||
msg: string;
|
||||
processed?: boolean;
|
||||
votedDirectors: string[];
|
||||
|
@ -30,10 +29,9 @@ const Proclamation = new Schema({
|
|||
present: Number,
|
||||
absent: Number,
|
||||
},
|
||||
acceptedAt: Number,
|
||||
msg: { type: String, required: true, unique: true },
|
||||
processed: Boolean,
|
||||
votedDirectors: Array,
|
||||
votedDirectors: { type: Array, required: true },
|
||||
});
|
||||
|
||||
export default model<ProclamationInterface>('Proclamations', Proclamation);
|
||||
|
|
|
@ -7,7 +7,6 @@ export { default as Member, MemberInterface } from './Member';
|
|||
export { default as Merchant, MerchantInterface } from './Merchant';
|
||||
export { default as Moderation, ModerationInterface } from './Moderation';
|
||||
export { default as Motion, MotionInterface } from './Motion';
|
||||
export { default as NNTrainingData, NNTrainingDataInterface } from './NNTrainingData';
|
||||
export { default as Note, NoteInterface } from './Note';
|
||||
export { default as PagerNumber, PagerNumberInterface, PagerNumberRaw } from './PagerNumber';
|
||||
export { default as Promo, PromoInterface } from './Promo';
|
||||
|
|
Loading…
Reference in New Issue