Large diffs are not rendered by default.

@@ -28,8 +28,8 @@ export class Choose extends Command {
// Range of Floats
if (range[2] || range[4]) {
const decimals = Math.min(Math.max(
this.countDecimals(parseFloat(range[1])),
this.countDecimals(parseFloat(range[3]))
this.countDecimals(range[1]),
this.countDecimals(range[3])
), 19);

return (min + Math.random() * (max - min)).toFixed(decimals);
@@ -6,18 +6,21 @@ export class Command {
constructor(client) {
this.client = client;
this.wholeWordBlacklist = [
'xd',
'!ruels',
'S ˙͜ >˙ A ˙͜ >˙ L ˙͜ >˙ S ˙͜ >˙ A',
'!random',
'!2hu',
'!anime',
'!nep',
];

this.blacklist = [
'.ly',
'!loli',
'!sw',
'!fish',
'.lewd',
'cooldudeirc',
'valbot',
'ciao',
'!ruels',
'S ˙͜ >˙ A ˙͜ >˙ L ˙͜ >˙ S ˙͜ >˙ A',
'!random',
'!2hu',
'!anime',
'!nep',
];
}

@@ -32,7 +35,7 @@ export class Command {

send(to, text) {
if (this.checkBlacklist(text)) {
this.client.say(to, 'Blacklist triggered.');
this.client.say(to, 'STOP SPAMMING COMMANDS YOU FUCKS');
} else {
this.client.say(to, text);
}
@@ -1,5 +1,6 @@
import debug from 'debug';
import fetch from 'node-fetch';
import config from './../../config';
import { Command } from './command.js';
import { addCommas } from '../modules/number_helpers.js';

@@ -30,7 +31,7 @@ export class Imgur extends Command {
info(id) {
const url = `https://api.imgur.com/3/image/${id}`;
const headers = new fetch.Headers();
headers.append('Authorization', `Client-ID ${process.env.IMGUR_CLIENT}`);
headers.append('Authorization', `Client-ID ${config.keys.imgur_client}`);

return fetch(url, { headers }).then(response => {
if (response.ok) {
@@ -0,0 +1,127 @@
import debug from 'debug';
import { Command } from './command.js';

const log = debug(`Nep`);

export class Nep extends Command {
constructor(client) {
super(client);

this.responses = [
'The best nep is Anonydeath! https://waa.ai/vkHI',
'The best nep is Copypaste! https://waa.ai/k04n',
'The best nep is 5pb! https://waa.ai/k00z',
'The best nep is Abnes! https://waa.ai/k00o',
'The best nep is Ai Masujima! https://waa.ai/k00X',
'The best nep is Arfoire! https://waa.ai/k003',
'The best nep is B-Sha! https://waa.ai/k00O',
'The best nep is Blanc! https://waa.ai/k00T',
'The best nep is White Heart! https://waa.ai/k00e',
'The best nep is Ultradimension White Heart! https://waa.ai/k00m',
'The best nep is Ultradimension Blanc! https://waa.ai/k00x',
'The best nep is Blossom Aisen! https://waa.ai/k00q',
'The best nep is Broccoli! https://waa.ai/k00l',
'The best nep is C-Sha! https://waa.ai/k00F',
'The best nep is Cave! https://waa.ai/k009',
'The best nep is CFW Magic! https://waa.ai/k00s',
'The best nep is Chika Hakozaki! https://waa.ai/k00c',
'The best nep is Compa! https://waa.ai/k00V',
'The best nep is Baby Compa! https://waa.ai/k00w',
'The best nep is Compile! https://waa.ai/k00H',
'The best nep is Croire! https://waa.ai/k00U',
'The best nep is Cyberconnect2! https://waa.ai/k00K',
'The best nep is Dangly! https://waa.ai/k00R',
'The best nep is Dark Purple! https://waa.ai/k00Q',
'The best nep is Deco! https://waa.ai/k002',
'The best nep is Dengekiko! https://waa.ai/kqCJ',
'The best nep is Ein Al! https://waa.ai/k00I',
'The best nep is Estelle! https://waa.ai/k008',
'The best nep is Falcom! https://waa.ai/k00W',
'The best nep is Ultradimension Falcom! https://waa.ai/k00i',
'The best nep is Famitsu! https://waa.ai/kqCm',
'The best nep is Generia! https://waa.ai/k00g',
'The best nep is God Eater! https://waa.ai/k00h',
'The best nep is Gust! https://waa.ai/k00P',
'The best nep is Histoire! https://waa.ai/k007',
'The best nep is Ultradimension Histoire! https://waa.ai/k00L',
'The best nep is IF! https://waa.ai/k00r',
'The best nep is Baby IF! https://waa.ai/k005',
'The best nep is Jackpot! https://waa.ai/k00n',
'The best nep is K-Sha! https://waa.ai/k00G',
'The best nep is Kei Jinguji! https://waa.ai/k09E',
'The best nep is Lady Wac! https://waa.ai/k09v',
'The best nep is Chun-Li! https://waa.ai/k09k',
'The best nep is Lid! https://waa.ai/k09z',
'The best nep is Linda! https://waa.ai/k09a',
'The best nep is Little Rain! https://waa.ai/k09o',
'The best nep is MAGES.! https://waa.ai/k09X',
'The best nep is MarvelousAQL! https://waa.ai/k09O',
'The best nep is Million Arthur! https://waa.ai/k09e',
'The best nep is Mina Nishizawa! https://waa.ai/4ZVw',
'The best nep is Moru! https://waa.ai/vVse',
'The best nep is Nepgear! https://waa.ai/k09J',
'The best nep is Purple Sister! https://waa.ai/k09m',
'The best nep is Ultradimension Nepgear! https://waa.ai/k09x',
'The best nep is Ultradimension Purple Sister! https://waa.ai/k09l',
'The best nep is Neptune! https://waa.ai/k099',
'The best nep is Purple Heart! https://waa.ai/k09S',
'The best nep is Ultradimension Neptune! https://waa.ai/k09f',
'The best nep is Ultradimension Purple Heart! https://waa.ai/k09c',
'The best nep is Adult Neptune! https://waa.ai/k09V',
'The best nep is Nisa! https://waa.ai/k09w',
'The best nep is Nitroplus! https://waa.ai/k09H',
'The best nep is Noire! https://waa.ai/k09K',
'The best nep is Black Heart! https://waa.ai/k09R',
'The best nep is Ultradimension Noire! https://waa.ai/k098',
'The best nep is Ultradimension Black Heart! https://waa.ai/k09I',
'The best nep is Peashy! https://waa.ai/k09W',
'The best nep is Yellow Heart! https://waa.ai/k09i',
'The best nep is Baby Peashy! https://waa.ai/k09D',
'The best nep is Plutia! https://waa.ai/k091',
'The best nep is Iris Heart! https://waa.ai/4bL4',
'The best nep is Poona! https://waa.ai/k096',
'The best nep is Ram! https://waa.ai/k09N',
'The best nep is White Sister (Ram)! https://waa.ai/k09h',
'The best nep is Red! https://waa.ai/k09P',
'The best nep is Rei Ryghts! https://waa.ai/k09p',
'The best nep is Rei Ryghts (HDD)! https://waa.ai/k09Z',
'The best nep is Resta! https://waa.ai/k097',
'The best nep is Rom! https://waa.ai/k09L',
'The best nep is White Sister (Rom)! https://waa.ai/k09b',
'The best nep is Ryuka! https://waa.ai/k09r',
'The best nep is S-Sha! https://waa.ai/k09n',
'The best nep is Sango! https://waa.ai/k09G',
'The best nep is Saori! https://waa.ai/k0SE',
'The best nep is Stella! https://waa.ai/k0S4',
'The best nep is Sting! https://waa.ai/k0Sv',
'The best nep is Tamsoft! https://waa.ai/k0Sj',
'The best nep is Tekken! https://waa.ai/4rV0',
'The best nep is Tiara! https://waa.ai/k0Sz',
'The best nep is Tsunemi! https://waa.ai/k0Sa',
'The best nep is Uni! https://waa.ai/k0So',
'The best nep is Black Sister! https://waa.ai/k0SX',
'The best nep is Uzume! https://waa.ai/k0S3',
'The best nep is Orange Heart! https://waa.ai/k0SO',
'The best nep is Vert! https://waa.ai/k0Su',
'The best nep is Green Heart! https://waa.ai/k0St',
'The best nep is Ultradimension Green Heart! https://waa.ai/k0Se',
'The best nep is Ultradimension Vert! https://waa.ai/k0ST',
'The best nep is Vio! https://waa.ai/k0Sm',
'The best nep is Wyn! https://waa.ai/k0SJ',

];
}

message(from, to, text) {
if (text.startsWith(`!ne`)) {
log(`${from} on: ${text}`);

const result = this.responses[Math.floor(Math.random() * this.responses.length)];
this.send(to, `${from}: ${result}`);
}
}

help(from) {
this.client.notice(from, `.8ball question; randomly outputs response`);
}
}

Large diffs are not rendered by default.

Large diffs are not rendered by default.

@@ -14,6 +14,20 @@ export class Reply extends Command {
this.responses.set('thx bot', 'np');
this.responses.set('bot pls', '( ¬‿¬)');
this.responses.set('.bugreport', 'Hi! To file a feature request or bug, go to: https://github.com/IanMitchell/ARX-7');
this.responses.set('!addquote', 'Please message zane the quote you want added.');
this.responses.set('!tuba', 'Whaaaaaaa whaaaaa whaaaaa');
this.responses.set('!auth', '/msg authserv@services.gamesurge.net zaneserv irule1');
this.responses.set('yes bot', '<3');
this.responses.set('!quotelist', 'You can find a quote list here: http://pastebin.com/BNJvwwCL');
this.responses.set('no bot', ':(');
this.responses.set("i'm bored", 'thanks for the update fuse');
this.responses.set('dang', 'Dang.');
this.responses.set('!badword', 'so how do you dang denim-wearing fatgays feel about modern warfare 3');
this.responses.set('!toymachine', 'http://rocksmith.ubi.com/rocksmith/en-us/buy/index.aspx');
this.responses.set('!silly', "<+'Silly> hey guys 69 is a funny number becuas eit is also a sexual position lol!");
this.responses.set('!greg', 'gerg');
this.responses.set('!gerg', 'greg');
this.responses.set('!scaruffi', 'The fact that so many books still name sfury as "the greatest or most significant or most influential" sperglord ever only tells you how far autism still is from becoming a serious art.');
}

message(from, to, text) {
@@ -1,15 +1,11 @@
import debug from 'debug';
import fetch from 'node-fetch';
import config from './../../config';
import { Command } from './command.js';
import moment from 'moment';
import { exactDate } from '../modules/dates';

const log = debug('Airing');

const SHOWTIMES = {
SERVER: process.env.SHOWTIMES_SERVER,
};

export class ShowtimesAiring extends Command {
message(from, to, text) {
if (text === '.airing') {
@@ -29,7 +25,7 @@ export class ShowtimesAiring extends Command {
}

airingRequest(channel) {
const uri = `${SHOWTIMES.SERVER}/shows.json?irc=${encodeURIComponent(channel)}`;
const uri = `${config.showtimes.server}/shows.json?irc=${encodeURIComponent(channel)}`;
return fetch(uri).then(response => {
if (response.ok) {
return response.json().then(data => this.createMessage(data));
@@ -50,8 +46,8 @@ export class ShowtimesAiring extends Command {
let message = 'Air dates: ';

json.shows.forEach(show => {
const date = exactDate(moment(new Date(show.air_date)));
message += `${show.name} #${show.episode_number} airs in ${date}, `;
const date = moment(new Date(show.air_date)).fromNow();
message += `${show.name} #${show.episode_number} airs ${date}, `;
});

return message.slice(0, -2);
@@ -1,14 +1,11 @@
import debug from 'debug';
import fetch from 'node-fetch';
import config from './../../config';
import { Command } from './command.js';
import colors from 'irc-colors';
import moment from 'moment';

const log = debug('Blame');
const SHOWTIMES = {
SERVER: process.env.SHOWTIMES_SERVER,
KEY: process.env.SHOWTIMES_KEY,
};

export class ShowtimesBlame extends Command {
message(from, to, text) {
@@ -34,7 +31,7 @@ export class ShowtimesBlame extends Command {
blameRequest(from, to, show, useNames = false) {
log(`Blame request by ${from} in ${to} for ${show}`);

let uri = `${SHOWTIMES.SERVER}/blame.json?`;
let uri = `${config.showtimes.server}/blame.json?`;
uri += `irc=${encodeURIComponent(to)}`;
uri += `&show=${encodeURIComponent(show.trim())}`;

@@ -66,7 +63,7 @@ export class ShowtimesBlame extends Command {
// Pending takes precedence
if (staff.finished && !status.has(staff.acronym)) {
status.set(staff.acronym, colors.bold.green(staff.acronym));
} else if (!staff.finished) {
} else {
status.set(staff.acronym, colors.bold.red(staff.acronym));

if (job === 'release') {
@@ -1,14 +1,10 @@
import debug from 'debug';
import fetch from 'node-fetch';
import config from './../../config';
import { Command } from './command.js';
import moment from 'moment';
import { exactDate } from '../modules/dates';

const log = debug('Next');
const SHOWTIMES = {
SERVER: process.env.SHOWTIMES_SERVER,
KEY: process.env.SHOWTIMES_KEY,
};

export class ShowtimesNext extends Command {
message(from, to, text) {
@@ -33,7 +29,7 @@ export class ShowtimesNext extends Command {

nextRequest(show) {
const name = encodeURIComponent(show.trim());
const uri = `${SHOWTIMES.SERVER}/shows/${name}.json`;
const uri = `${config.showtimes.server}/shows/${name}.json`;

return fetch(uri).then(response => {
if (response.ok) {
@@ -52,8 +48,8 @@ export class ShowtimesNext extends Command {
return json.message;
}

const date = exactDate(moment(new Date(json.air_date)));
return `Air date: ${json.name} #${json.episode_number} airs in ${date}`;
const date = moment(new Date(json.air_date)).fromNow();
return `Air date: ${json.name} #${json.episode_number} airs ${date}`;
}

help(from) {
@@ -1,13 +1,11 @@
import debug from 'debug';
import FormData from 'form-data';
import fetch from 'node-fetch';
import config from './../../config';
import { Command } from './command.js';

const log = debug('Release');
const SHOWTIMES = {
SERVER: process.env.SHOWTIMES_SERVER,
KEY: process.env.SHOWTIMES_KEY,
};
const SHOWTIMES_URL = `${config.showtimes.server}`;

export class ShowtimesRelease extends Command {
constructor(client, authorized) {
@@ -40,9 +38,9 @@ export class ShowtimesRelease extends Command {
const form = new FormData();
form.append('irc', to);
form.append('name', show.trim());
form.append('auth', SHOWTIMES.KEY);
form.append('auth', config.showtimes.key);

return fetch(`${SHOWTIMES.SERVER}/release`, { method: 'PUT', body: form }).then(response => {
return fetch(`${SHOWTIMES_URL}/release`, { method: 'PUT', body: form }).then(response => {
if (response.ok) {
return response.json().then(data => data.message);
}
@@ -1,15 +1,12 @@
import debug from 'debug';
import FormData from 'form-data';
import fetch from 'node-fetch';
import config from './../../config';
import { Command } from './command.js';
import { ShowtimesBlame } from './showtimes_blame.js';

const SHOWTIMES = {
SERVER: process.env.SHOWTIMES_SERVER,
KEY: process.env.SHOWTIMES_KEY,
};

const log = debug('Showtimes');
const SHOWTIMES_URL = `${config.showtimes.server}`;

export class ShowtimesStaff extends Command {
constructor(client, authorized) {
@@ -19,21 +16,13 @@ export class ShowtimesStaff extends Command {
}

message(from, to, text) {
const showtimesRegex = /^(?:[.!])(?:(?:(done|undone) (tl|tlc|enc|ed|tm|ts|qc) (.+))|(?:(?:(done|undone) (.+?)(?: !(\w+))?)))$/i;
const showtimesRegex = /^[.!](done|undone)(?:\s)(.+?)(?:\s!(\w+))?$/i;
const showtimes = text.match(showtimesRegex);

if (showtimes) {
this.isAuthorized(from).then(auth => {
if (auth) {
let status = null;
let position = null;
let show = null;

if (showtimes[2]) {
[, status, position, show] = showtimes;
} else {
[,,,, status, show, position] = showtimes;
}
const [, status, show, position] = showtimes;

this.showtimesRequest(from, to, status, show, position).then(response => {
const msg = response;
@@ -59,13 +48,13 @@ export class ShowtimesStaff extends Command {
form.append('status', this.convertStatus(status));
form.append('irc', to);
form.append('name', show.trim());
form.append('auth', SHOWTIMES.KEY);
form.append('auth', config.showtimes.key);

if (position) {
form.append('position', position);
}

return fetch(`${SHOWTIMES.SERVER}/staff`, { method: 'PUT', body: form }).then(response => {
return fetch(`${SHOWTIMES_URL}/staff`, { method: 'PUT', body: form }).then(response => {
if (response.ok) {
return response.json().then(data => data.message);
}
@@ -0,0 +1,77 @@
import debug from 'debug';
import FormData from 'form-data';
import fetch from 'node-fetch';
import config from './../../config';
import { Command } from './command.js';
import { ShowtimesBlame } from './showtimes_blame.js';

const log = debug('Showtimes');
const SHOWTIMES_URL = `${config.showtimes.server}`;

export class ShowtimesStatus extends Command {
constructor(client, authorized) {
super(client);
this.isAuthorized = authorized;
this.blame = new ShowtimesBlame(client);
}

message(from, to, text) {
const showtimesRegex = /^[.!](done|undone)(?:\s)(.+?)(?:\s!(\w+))?$/i;
const showtimes = text.match(showtimesRegex);

if (showtimes) {
this.isAuthorized(from).then(auth => {
if (auth) {
const [, status, show, position] = showtimes;

this.showtimesRequest(from, to, status, show, position).then(response => {
const msg = response;

this.blame.blameRequest(from, to, show, true).then(res => {
this.send(to, `${msg}. ${res}`);
});
}, error => {
this.send(to, 'Error connecting to Deschtimes');
log(`Error: ${error.message}`);
return error;
});
}
});
}
}

showtimesRequest(from, to, status, show, position) {
log(`Request by ${from} in ${to} for ${show} [${position}]: ${status}`);

const form = new FormData();
form.append('username', from);
form.append('status', this.convertStatus(status));
form.append('irc', to);
form.append('name', show.trim());
form.append('auth', config.showtimes.key);

if (position) {
form.append('position', position);
}

return fetch(`${SHOWTIMES_URL}/staff`, { method: 'PUT', body: form }).then(response => {
if (response.ok) {
return response.json().then(data => data.message);
}

return response.json().then(data => Error(data.message));
}).catch(error => Error(error));
}

convertStatus(status) {
if (status === 'done') {
return 'true';
}

return 'false';
}

help(from) {
this.client.notice(from, `.(done|undone) show [!position]; marks (optional) position as done.`);
}
}
@@ -0,0 +1,172 @@
import debug from 'debug';
import { Command } from './command.js';

const log = debug('Touhou');

export class Touhou extends Command {
constructor(client) {
super(client);

this.responses = [
'The best 2hu is Reimu Hakurei!',
'The best 2hu is Shingyoku!',
'The best 2hu is YuugenMagan!',
'The best 2hu is Elis!',
'The best 2hu is Sariel!',
'The best 2hu is Kikuri!',
'The best 2hu is Konngara!',
'The best 2hu is Genjii!',
'The best 2hu is Clownpiece!',
'The best 2hu is Hecatia Lapislazuli!',
'The best 2hu is Junko!',
'The best 2hu is Sagume Kishin!',
'The best 2hu is Doremy Sweet!',
'The best 2hu is Ringo!',
'The best 2hu is Seiran!',
"The best 2hu is Sumireko Usami!",
'The best 2hu is Rika!',
'The best 2hu is Meira!',
'The best 2hu is Marisa Kirsame!',
'The best 2hu is Evil Eye Sigma!',
'The best 2hu is Ellen!',
'The best 2hu is Kotohime!',
'The best 2hu is Kana Anaberal!',
'The best 2hu is Rikako Asakura!',
'The best 2hu is Chiyuri Kitashirakawa!',
'The best 2hu is Yumemi Okazaki!',
'The best 2hu is Ruukoto!',
'The best 2hu is Orange!',
'The best 2hu is Kurumi!',
'The best 2hu is Elly!',
'The best 2hu is Yuuka Kazami!',
'The best 2hu is Mugetsu!',
'The best 2hu is Gengetsu!',
'The best 2hu is Sara!',
'The best 2hu is Luize!',
'The best 2hu is Alice Margatroid!',
'The best 2hu is Yuki!',
'The best 2hu is Mai!',
'The best 2hu is Yumeko!',
'The best 2hu is Shinki!',
'The best 2hu is Rumia!',
'The best 2hu is Daiyousei!',
'The best 2hu is Hong Meiling!',
'The best 2hu is Koakuma!',
'The best 2hu isn`t Patchouli Knowledge!',
'The best 2hu is Sakuya Izayoi!',
'The best 2hu is Remilia Scarlet!',
'The best 2hu is Flandre Scarlet!',
'The best 2hu is Letty Whiterock!',
'The best 2hu is CHEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEN!',
'The best 2hu is Lily White!',
'The best 2hu is Layla Prismriver!',
'The best 2hu is Lunasa Prismriver!',
'The best 2hu is Merlin Prismriver!',
'The best 2hu is Lyrica Prismriver!',
'The best 2hu is Youmu Konpaku!',
'The best 2hu is Youki Konpaku!',
'The best 2hu is Yuyuko Saigyouji!',
'The best 2hu is Saigyou Ayakashi!',
'The best 2hu isn`t Ran Yakumo!',
'The best 2hu is Ran Yakumo!',
'The best 2hu is Yukari Yakumo!',
'The best 2hu is Suika Ibuki!',
'The best 2hu is Wriggle Nightbug!',
'The best 2hu is Mystia Lorelei!',
'The best 2hu is birb!',
'The best 2hu is Keine Kamishirasawa!',
'The best 2hu is Tewi Inaba!',
'The best 2hu is Reisen Udongein Inaba!',
'The best 2hu is it`s pronounced Reisen not Reisen!',
'The best 2hu is Eirin Yagokro!',
'The best 2hu is Kaguya Houraisan!',
'The best 2hu is Fujiwara no Mokou!',
'The best 2hu is Aya Shameimaru!',
'The best 2hu is Ayayayayayayayayayaya!',
'The best 2hu is Medicine Melancholy!',
'The best 2hu is Komachi Onozuka!',
'The best 2hu is Eiki Shiki, Yamaxanadu!',
'The best 2hu is Shizuha Aki!',
'The best 2hu is Minoriko Aki!',
'The best 2hu is Hina Kagiyama!',
'The best 2hu is Nitori Kawashiro!',
'The best 2hu is Momiji Inubashiri! awoo~',
'The best 2hu is Sanae Kochiya!',
'The best 2hu is Sanaynay!',
'The best 2hu is Kanako Yasaka!',
'The best 2hu is Suwako Moriya!',
'The best 2hu is Iku Nagae!',
'The best 2hu is Tenshi Hinanawi!',
'The best 2hu is Kisume!',
'The best 2hu is Yamame Kurodani!',
'The best 2hu is Parsee Mizuhashi!',
'The best 2hu is Yuugi Hoshiguma!',
'The best 2hu is Satori Komeji!',
'The best 2hu is Rin Kaenbyou!',
'The best 2hu is Utsuho Reiuji!',
'The best 2hu is Koishi Komeiji!',
'The best 2hu is Nazrin!',
'The best 2hu is Kogasa Tatara!',
'The best 2hu is Ichirin Kumoi!',
'The best 2hu is Unzan!',
'The best 2hu is Kogasa Tatara!',
'The best 2hu is Ichirin Kumoi!',
'The best 2hu is Unzan!',
'The best 2hu is Minamitsu Murasa!',
'The best 2hu is Shou Toramaru!',
'The best 2hu is Byakuren Hijiri!',
'The best 2hu is Youkai Jesus!',
'The best 2hu is Myouren!',
'The best 2hu is Nue Houjuu!',
'The best 2hu is The Catfish!',
'The best 2hu is Hatate Himekaidou!',
'The best 2hu is Kyouko Kasodani!',
'The best 2hu is Yoshika Miyako!',
'The best 2hu is Seiga Kaku!',
'The best 2hu is Soga no Tojiko!',
'The best 2hu is Mononobe no Futo!',
'The best 2hu is Toyosatomimi no Miko!',
'The best 2hu is Mamizou Futatsuiwa!',
'The best 2hu is Hata no Kokoro!',
'The best 2hu is Wakasagihime!',
'The best 2hu is Sekibanki!',
'The best 2hu is Kagerou Imaizumi!',
'The best 2hu is Benben Tsukumo!',
'The best 2hu is Yatsuhashi Tsukumo!',
'The best 2hu is Seija Kijin!',
'The best 2hu is Shinmyoumaru Sukuna!',
'The best 2hu is Raiko Horikawa!',
'The best 2hu is not Rinnosuke Morichika!',
'The best 2hu is Tokiko!',
'The best 2hu is Maribel Hearn!',
'The best 2hu is Renko Usami!',
'The best 2hu is Sunny Milk!',
'The best 2hu is Luna Child!',
'The best 2hu is Star Sapphire!',
'The best 2hu is Heida no Akyuu!',
'The best 2hu is Reisen II!',
'The best 2hu is Watatsuki no Yorihime!',
'The best 2hu is Watatsuki no Toyohime!',
'The best 2hu is Kasen Ibaraki!',
'The best 2hu is it`s pronounced Kasen not Kasen!',
'The best 2hu is Kosuzu Motoori!',
'The best 2hu is Rin Satsuki!',
'The best 2hu is Tenma!',
'The best 2hu is none of them!',
'The best 2hu is all of them!',
];
}

message(from, to, text) {
if (text.startsWith('!2h')) {
log(`${from} on: ${text}`);

const result = this.responses[Math.floor(Math.random() * this.responses.length)];
this.send(to, `${from}: ${result}`);
}
}

help(from) {
this.client.notice(from, `.8ball question; randomly outputs response`);
}
}
@@ -1,8 +1,8 @@
import debug from 'debug';
import he from 'he';
import TwitterClient from 'twitter';
import config from './../../config';
import { Command } from './command.js';
import { ProtectedError } from '../modules/custom_errors';

const log = debug('Twitter');

@@ -18,13 +18,8 @@ export class Twitter extends Command {
return this.info(match[2], match[4]).then(tweet => {
this.send(to, `[Twitter]: ${tweet.text} | By ${tweet.username} (@${match[2]})`);
}, error => {
if (error instanceof ProtectedError) {
this.send(to, error.message);
} else {
log(error);
this.send(to, 'Sorry, could not find Twitter info.');
}

this.send(to, 'Twitter is currently broken, please voice your frustrations to @_desch_.');
log(error);
return error;
});
}
@@ -35,10 +30,10 @@ export class Twitter extends Command {

info(username, tweetId) {
const client = new TwitterClient({
consumer_key: process.env.TWITTER_CONSUMER,
consumer_secret: process.env.TWITTER_CONSUMER_SECRET,
access_token_key: process.env.TWITTER_ACCESS_TOKEN,
access_token_secret: process.env.TWITTER_ACCESS_TOKEN_SECRET,
consumer_key: config.keys.twitter_consumer,
consumer_secret: config.keys.twitter_consumer_secret,
access_token_key: config.keys.twitter_access_token,
access_token_secret: config.keys.twitter_access_token_secret,
});

return new Promise((resolve, reject) => {
@@ -48,11 +43,6 @@ export class Twitter extends Command {
return reject(Error(`Twitter Info Request Error: ${error}`));
}

if (tweet.user.protected) {
log('Protected tweet linked');
return reject(new ProtectedError(`@${tweet.user.name} is a protected account.`));
}

try {
return resolve({
// Remove linebreaks
@@ -1,5 +1,6 @@
import debug from 'debug';
import fetch from 'node-fetch';
import config from './../../config';
import { Command } from './command.js';
import { addCommas } from '../modules/number_helpers.js';

@@ -44,7 +45,7 @@ export class Youtube extends Command {

info(id) {
const uri = `https://www.googleapis.com/youtube/v3/videos` +
`?id=${id}&alt=json&key=${process.env.YOUTUBE}` +
`?id=${id}&alt=json&key=${config.keys.youtube}` +
`&fields=items(id,snippet(channelId,title),contentDetails,statistics)` +
`&part=snippet,statistics,contentDetails`;

@@ -59,7 +60,7 @@ export class Youtube extends Command {

const video = {
title: data.items[0].snippet.title,
// time: moment.duration(data.items[0].contentDetails.duration),
//time: moment.duration(data.items[0].contentDetails.duration),
views: addCommas(data.items[0].statistics.viewCount),
};

@@ -83,7 +84,7 @@ export class Youtube extends Command {
search(title) {
const uri = `https://www.googleapis.com/youtube/v3/search?part=snippet` +
`&q=${encodeURIComponent(title.trim())}` +
`&key=${process.env.YOUTUBE}`;
`&key=${config.keys.youtube}`;

return fetch(uri).then(response => {
if (response.ok) {
@@ -0,0 +1,40 @@
import 'babel-polyfill';
import { describe, before, beforeEach, afterEach, it } from 'mocha';
import assert from 'assert';
import { Client } from '../helpers.js';
import { ShowtimesStatus } from '../../src/commands/showtimes_status';

const client = new Client();
const showtimes = new ShowtimesStatus(client, null);

describe('Blame', () => {
describe('Triggers', () => {
beforeEach(() => showtimes.isAuthorized = () => new Promise(resolve => resolve(true)));

it('should respond to .done trigger');

it('should respond to .undone trigger');

it('should not activate in middle of phrase');

it('should be case insensitive');
});

describe('General Usage', () => {
it('should respond in correct channel');

it('should be restricted to authorized members');

it('should identify optional position');
});

// To avoid repeatedly spamming endpoint, we only hit the API once. The
// lastMessage contains the results; these tests don't need fresh results.
describe('Message Formatting', () => {
// before(() => showtimes.message('Mocha', '#arx-7', '.done aoty'));

it('should should include blame');

it('should include staff name');
});
});
@@ -106,7 +106,7 @@ describe('ARX-7', () => {
it('should respond to Query', () => {
arx7.message('Mocha', 'ARX-7', 'Hi');
assert(client.lastMessage, 'Query response incorrect');
assert(client.lastMessage.includes('Desch, Jukey, Fyurie'), 'Query admin list incorrect');
assert(client.lastMessage.includes('Desch, Jukey, Aoi-chan'), 'Query admin list incorrect');
});

it('should respond to Admin Query', () => {
@@ -1,14 +1,15 @@
{
"name": "ARX-7",
"password": "password",
"server": "irc.rizon.net",
"port": 6667,
"ssl": false,
"userName": "chidori",
"admins": ["Desch", "Jukey", "Fyurie"],
"admins": ["Desch", "Jukey", "Aoi-chan"],
"channels": [
{
"name": "#arbalest",
"key": true,
"key": "sagara",
"plugins": [
"choose"
]