added embed support to lang

This commit is contained in:
2022-02-14 14:37:10 -06:00
parent 28fb9ed3c8
commit 458d3f3d76
5 changed files with 450 additions and 57 deletions

View File

@@ -17,6 +17,10 @@
"allowNumber" : false "allowNumber" : false
} }
], ],
/* dev */
"no-debugger": "off",
/* important */ /* important */
"prefer-const": "error", "prefer-const": "error",
"quotes": ["error", "single"], "quotes": ["error", "single"],

26
dist/api.js vendored
View File

@@ -25,9 +25,9 @@ Object.defineProperty(exports, "__esModule", { value: true });
exports.getPlayerInteraction = exports.getPlayer = void 0; exports.getPlayerInteraction = exports.getPlayer = void 0;
/*eslint prefer-const: "error"*/ /*eslint prefer-const: "error"*/
const cheerio = __importStar(require("cheerio")); const cheerio = __importStar(require("cheerio"));
const discord_js_1 = require("discord.js");
const https_1 = __importDefault(require("https")); const https_1 = __importDefault(require("https"));
const util_1 = require("./util"); const util_1 = require("./util");
const Lang = __importStar(require("./lang"));
const uniteApiRegex = { const uniteApiRegex = {
//$1 = name, $2 = id //$1 = name, $2 = id
ogtitle: /unite api - (.+) \((.*)\)/i, ogtitle: /unite api - (.+) \((.*)\)/i,
@@ -187,18 +187,18 @@ async function sendPlayerEmbed(interaction, data) {
eloStr = `(${data.elo})`; eloStr = `(${data.elo})`;
else else
eloStr = `Class ${data.class}`; eloStr = `Class ${data.class}`;
const embed = new discord_js_1.MessageEmbed() await interaction.editReply(Lang.getEmbed('api.player', {
.setTitle(`${data.name} (${data.id})`) name: data.name,
.setURL(`https://uniteapi.dev/p/${encodeURIComponent(data.name)}`) id: data.id,
.setTimestamp() nameEncoded: encodeURIComponent(data.name),
.setThumbnail(data.avatar) avatar: data.avatar,
.setDescription(`Level ${data.level} level: data.level,
${data.rank} ${eloStr} rank: data.rank,
elo: eloStr,
**Battles** ${data.battles} battles: data.battles,
**Wins** ${data.wins} wins: data.wins,
**Win Rate** ${data.winrate}`); winrate: data.winrate
await interaction.editReply({ embeds: [embed] }); }));
} }
/** /**
* calls getPlayer() with the name from the interaction * calls getPlayer() with the name from the interaction

160
dist/lang.js vendored
View File

@@ -1,6 +1,100 @@
"use strict"; "use strict";
Object.defineProperty(exports, "__esModule", { value: true }); Object.defineProperty(exports, "__esModule", { value: true });
exports.get = exports.setLang = void 0; exports.getEmbed = exports.get = exports.setLang = void 0;
const discord_js_1 = require("discord.js");
/* UTIL FUNCS */
function template(str, args) {
return str.replace(/{\w+}/g, str => {
const key = str.substring(1, str.length - 1);
if (key in args)
return args[key];
return key;
});
}
function bigString(str) {
if (typeof str === 'object')
return str.join('\n');
return str;
}
function resolveColor(color) {
color = color.replace(/[^0-9a-f]/gi, '');
const colorNum = [0, 0, 0];
if (color.length === 3 || color.length === 6) {
const colorSpl = /([0-9a-f]{1,2})([0-9a-f]{1,2})([0-9a-f]{1,2})/.exec(color);
if (!colorSpl)
return colorNum;
for (let i = 0; i < colorSpl.length && i < colorNum.length; i++)
colorNum[i] = parseInt(colorSpl[i], 16);
}
return colorNum;
}
function embedObjStr(embedData, fallback = '') {
if (embedData.content !== undefined)
return bigString(embedData.content);
if (embedData.description !== undefined)
return bigString(embedData.description);
return fallback;
}
function embedObjEmbed(embedObj, args = {}) {
const embed = new discord_js_1.MessageEmbed(), { author, color, description, fields, footer, image, thumbnail, timestamp, title, url } = embedObj;
if (author !== undefined) {
let authorFix;
if (typeof author === 'string')
authorFix = {
name: template(author, args)
};
else {
const { name, icon, url } = author;
authorFix = {
name: template(name, args)
};
if (icon !== undefined)
authorFix.icon = template(icon, args);
if (url !== undefined)
authorFix.url = template(url, args);
}
embed.setAuthor(authorFix);
}
if (footer !== undefined) {
let footerFix;
if (typeof footer === 'string')
footerFix = {
text: template(footer, args)
};
else {
const { text, icon } = footer;
footerFix = {
text: template(text, args)
};
if (icon !== undefined)
footerFix.icon = template(icon, args);
}
embed.setFooter(footerFix);
}
if (color !== undefined)
embed.setColor(resolveColor(template(color, args)));
if (description !== undefined)
embed.setDescription(template(bigString(description), args));
if (image !== undefined)
embed.setImage(template(image, args));
if (thumbnail !== undefined)
embed.setThumbnail(template(thumbnail, args));
if (title !== undefined)
embed.setTitle(template(title, args));
if (url !== undefined)
embed.setURL(template(url, args));
if (timestamp === true)
embed.setTimestamp();
else if (typeof timestamp === 'string')
embed.setTimestamp(new Date(template(timestamp, args)));
else if (timestamp !== false)
embed.setTimestamp(timestamp);
fields?.forEach(field => {
embed.addField(template(field.name, args), template(bigString(field.value), args), field.inline);
});
return embed;
}
/* LANG */
const LANG = { const LANG = {
en: { en: {
main: { main: {
@@ -13,6 +107,23 @@ const LANG = {
join: 'Joined the queue', join: 'Joined the queue',
leave: 'Left the queue' leave: 'Left the queue'
}, },
api: {
player: {
embed: true,
title: '{name} ({id})',
url: 'https://uniteapi.dev/p/{nameEncoded}',
timestamp: true,
thumbnail: '{avatar}',
description: [
'Level {level}',
'{rank} {elo}',
'',
'**Battles** {battles}',
'**Wins** {wins}',
'**Win Rate** {winrate}'
]
}
},
error: { error: {
main: { main: {
missingToken: 'Missing Discord Token, please enter the bot token into the token file' missingToken: 'Missing Discord Token, please enter the bot token into the token file'
@@ -35,6 +146,7 @@ const LANG = {
} }
} }
}; };
/* MAIN */
let LANGID = 'en'; let LANGID = 'en';
if (!(LANGID in LANG)) if (!(LANGID in LANG))
throw 'language id does not exist'; throw 'language id does not exist';
@@ -45,16 +157,8 @@ function setLang(langid) {
throw 'language id does not exist'; throw 'language id does not exist';
} }
exports.setLang = setLang; exports.setLang = setLang;
function template(str, args) {
return str.replace(/{\w+}/g, str => {
const key = str.substring(1, str.length - 1);
if (key in args)
return args[key];
return key;
});
}
/** /**
* reads language json * reads language json (just strings)
* @param id ex: discord.error.noActiveQueue * @param id ex: discord.error.noActiveQueue
* @returns language value, defaults to `id` parameter * @returns language value, defaults to `id` parameter
*/ */
@@ -66,6 +170,8 @@ function get(id, args = {}) {
const found = finding[key]; const found = finding[key];
if (typeof found === 'string') if (typeof found === 'string')
return template(found, args); return template(found, args);
if (found.embed === true)
return embedObjStr(found, id);
finding = found; finding = found;
} }
else else
@@ -74,3 +180,37 @@ function get(id, args = {}) {
return id; return id;
} }
exports.get = get; exports.get = get;
/**
* reads language json as an object (could be embed or just string)
* @param id ex: discord.error.noActiveQueue
* @returns language value, defaults to `id` parameter
*/
function getEmbed(id, args = {}) {
const embedData = {
embeds: []
};
const keySpl = id.split('.').map(k => k.trim()).filter(k => k);
let finding = LANG[LANGID];
for (const key of keySpl) {
if (key in finding) {
const found = finding[key];
if (typeof found === 'string') {
embedData.content = template(found, args);
break;
}
if (found.embed === true) {
const embedObj = found, { content } = embedObj, embed = embedObjEmbed(embedObj, args), embedData = {
embeds: [embed]
};
if (content !== undefined)
embedData.content = content;
return embedData;
}
finding = found;
}
else
break;
}
return embedData;
}
exports.getEmbed = getEmbed;

View File

@@ -1,9 +1,10 @@
/*eslint prefer-const: "error"*/ /*eslint prefer-const: "error"*/
import * as cheerio from 'cheerio'; import * as cheerio from 'cheerio';
import { CommandInteraction, MessageEmbed } from 'discord.js'; import { CommandInteraction } from 'discord.js';
import { IncomingMessage } from 'http'; import { IncomingMessage } from 'http';
import http from 'https'; import http from 'https';
import { emsg } from './util'; import { emsg } from './util';
import * as Lang from './lang';
const uniteApiRegex = { const uniteApiRegex = {
//$1 = name, $2 = id //$1 = name, $2 = id
@@ -91,6 +92,7 @@ function readHTML(html: string): uniteApiData {
wins: '', wins: '',
winrate: '' winrate: ''
}; };
let metaElems = $('meta').toArray(); let metaElems = $('meta').toArray();
//filter down to just ones named "og:..." //filter down to just ones named "og:..."
@@ -227,19 +229,18 @@ async function sendPlayerEmbed(interaction: CommandInteraction, data: uniteApiDa
else else
eloStr = `Class ${data.class}`; eloStr = `Class ${data.class}`;
const embed = new MessageEmbed() await interaction.editReply(Lang.getEmbed('api.player', {
.setTitle(`${data.name} (${data.id})`) name: data.name,
.setURL(`https://uniteapi.dev/p/${encodeURIComponent(data.name)}`) id: data.id,
.setTimestamp() nameEncoded: encodeURIComponent(data.name),
.setThumbnail(data.avatar) avatar: data.avatar,
.setDescription(`Level ${data.level} level: data.level,
${data.rank} ${eloStr} rank: data.rank,
elo: eloStr,
**Battles** ${data.battles} battles: data.battles,
**Wins** ${data.wins} wins: data.wins,
**Win Rate** ${data.winrate}`); winrate: data.winrate
}));
await interaction.editReply({embeds: [embed]});
} }
/** /**

View File

@@ -1,6 +1,197 @@
type LangObj = { [keys:string]: LangObj | string } import { MessageEmbed } from 'discord.js';
/* TYPES */
type basicObject = {[keys: string]: string};
type URL = string;
type bigString = string | string[];
interface embedData {
content?: string,
embeds: MessageEmbed[]
}
interface embedField {
name: string,
value: bigString,
inline?: boolean
}
interface authorData {
name: string,
url?: string,
icon?: string
}
interface footerData {
text: string,
icon?: string
}
interface embedObj {
embed: true,
content?: string,
title?: string,
description?: bigString,
url?: URL,
color?: string,
footer?: string | footerData,
thumbnail?: URL,
image?: URL,
author?: string | authorData,
fields?: embedField[],
timestamp?: boolean | string | number
}
type LangObj = { [keys:string]: LangObj | embedObj | string }
type LangObjWhole = { [langid:string]: LangObj } type LangObjWhole = { [langid:string]: LangObj }
/* UTIL FUNCS */
function template(str: string, args: basicObject): string {
return str.replace(/{\w+}/g, str => {
const key = str.substring(1, str.length-1);
if (key in args)
return args[key];
return key;
});
}
function bigString(str: bigString): string {
if (typeof str === 'object')
return str.join('\n');
return str;
}
function resolveColor(color: string): [number, number, number] {
color = color.replace(/[^0-9a-f]/gi, '');
const colorNum: [number, number, number] = [0, 0, 0];
if (color.length === 3 || color.length === 6) {
const colorSpl = /([0-9a-f]{1,2})([0-9a-f]{1,2})([0-9a-f]{1,2})/.exec(color);
if (!colorSpl)
return colorNum;
for (let i = 0; i < colorSpl.length && i < colorNum.length; i++)
colorNum[i] = parseInt(colorSpl[i], 16);
}
return colorNum;
}
function embedObjStr(embedData: embedObj, fallback = ''): string {
if (embedData.content !== undefined)
return bigString(embedData.content);
if (embedData.description !== undefined)
return bigString(embedData.description);
return fallback;
}
function embedObjEmbed(embedObj: embedObj, args: basicObject = {}): MessageEmbed {
const embed = new MessageEmbed(),
{ author, color, description, fields, footer, image, thumbnail, timestamp, title, url } = embedObj;
if (author !== undefined) {
let authorFix: authorData;
if (typeof author === 'string')
authorFix = {
name: template(author, args)
};
else {
const {name, icon, url} = author;
authorFix = {
name: template(name, args)
};
if (icon !== undefined)
authorFix.icon = template(icon, args);
if (url !== undefined)
authorFix.url = template(url, args);
}
embed.setAuthor(authorFix);
}
if (footer !== undefined) {
let footerFix: footerData;
if (typeof footer === 'string')
footerFix = {
text: template(footer, args)
};
else {
const {text, icon} = footer;
footerFix = {
text: template(text, args)
};
if (icon !== undefined)
footerFix.icon = template(icon, args);
}
embed.setFooter(footerFix);
}
if (color !== undefined)
embed.setColor(resolveColor(template(color, args)));
if (description !== undefined)
embed.setDescription(template(bigString(description), args));
if (image !== undefined)
embed.setImage(template(image, args));
if (thumbnail !== undefined)
embed.setThumbnail(template(thumbnail, args));
if (title !== undefined)
embed.setTitle(template(title, args));
if (url !== undefined)
embed.setURL(template(url, args));
if (timestamp === true)
embed.setTimestamp();
else if (typeof timestamp === 'string')
embed.setTimestamp(new Date(template(timestamp, args)));
else if (timestamp !== false)
embed.setTimestamp(timestamp);
fields?.forEach(field => {
embed.addField(template(field.name, args), template(bigString(field.value), args), field.inline);
});
return embed;
}
/* LANG */
const LANG: LangObjWhole = { const LANG: LangObjWhole = {
en: { en: {
@@ -17,6 +208,24 @@ const LANG: LangObjWhole = {
leave: 'Left the queue' leave: 'Left the queue'
}, },
api: {
player: {
embed: true,
title: '{name} ({id})',
url: 'https://uniteapi.dev/p/{nameEncoded}',
timestamp: true,
thumbnail: '{avatar}',
description: [
'Level {level}',
'{rank} {elo}',
'',
'**Battles** {battles}',
'**Wins** {wins}',
'**Win Rate** {winrate}'
]
}
},
error: { error: {
main: { main: {
@@ -47,6 +256,7 @@ const LANG: LangObjWhole = {
}; };
/* MAIN */
let LANGID = 'en'; let LANGID = 'en';
if (!(LANGID in LANG)) if (!(LANGID in LANG))
@@ -59,27 +269,12 @@ export function setLang(langid: string) {
throw 'language id does not exist'; throw 'language id does not exist';
} }
function template(str: string, args: {[keys: string]: string}): string {
return str.replace(/{\w+}/g, str => {
const key = str.substring(1, str.length-1);
if (key in args)
return args[key];
return key;
});
}
/** /**
* reads language json * reads language json (just strings)
* @param id ex: discord.error.noActiveQueue * @param id ex: discord.error.noActiveQueue
* @returns language value, defaults to `id` parameter * @returns language value, defaults to `id` parameter
*/ */
export function get(id: string, args: {[keys: string]: string} = {}): string {//discord.error.noActiveQueue export function get(id: string, args: basicObject = {}): string {
const keySpl = id.split('.').map(k => k.trim()).filter(k => k); const keySpl = id.split('.').map(k => k.trim()).filter(k => k);
@@ -94,7 +289,10 @@ export function get(id: string, args: {[keys: string]: string} = {}): string {//
if (typeof found === 'string') if (typeof found === 'string')
return template(found, args); return template(found, args);
finding = found; if (found.embed === true)
return embedObjStr(found as embedObj, id);
finding = found as LangObj;
} else } else
break; break;
@@ -102,4 +300,54 @@ export function get(id: string, args: {[keys: string]: string} = {}): string {//
} }
return id; return id;
} }
/**
* reads language json as an object (could be embed or just string)
* @param id ex: discord.error.noActiveQueue
* @returns language value, defaults to `id` parameter
*/
export function getEmbed(id: string, args: basicObject = {}): embedData {
const embedData: embedData = {
embeds: []
};
const keySpl = id.split('.').map(k => k.trim()).filter(k => k);
let finding = LANG[LANGID];
for (const key of keySpl) {
if (key in finding) {
const found = finding[key];
if (typeof found === 'string') {
embedData.content = template(found, args);
break;
}
if (found.embed === true) {
const embedObj = found as embedObj,
{content} = embedObj,
embed = embedObjEmbed(embedObj, args),
embedData: embedData = {
embeds: [embed]
};
if (content !== undefined)
embedData.content = content;
return embedData;
}
finding = found as LangObj;
} else
break;
}
return embedData;
}