mirror of
https://github.com/BluemediaDev/muse.git
synced 2025-05-09 11:41:36 +02:00
Bump linter version
This commit is contained in:
parent
fd782219ef
commit
dcac22832d
28 changed files with 184 additions and 198 deletions
|
@ -67,7 +67,7 @@ export default class {
|
|||
let handler: Command;
|
||||
|
||||
if (this.commands.has(command)) {
|
||||
handler = this.commands.get(command) as Command;
|
||||
handler = this.commands.get(command)!;
|
||||
} else if (shortcut) {
|
||||
const possibleHandler = this.commands.get(shortcut.command.split(' ')[0]);
|
||||
|
||||
|
|
|
@ -9,7 +9,7 @@ export default class implements Command {
|
|||
public name = 'clear';
|
||||
public aliases = ['c'];
|
||||
public examples = [
|
||||
['clear', 'clears all songs in queue except currently playing']
|
||||
['clear', 'clears all songs in queue except currently playing'],
|
||||
];
|
||||
|
||||
public requiresVC = true;
|
||||
|
|
|
@ -10,7 +10,7 @@ export default class implements Command {
|
|||
public aliases = [];
|
||||
public examples = [
|
||||
['config prefix !', 'set the prefix to !'],
|
||||
['config channel music-commands', 'bind the bot to the music-commands channel']
|
||||
['config channel music-commands', 'bind the bot to the music-commands channel'],
|
||||
];
|
||||
|
||||
public async execute(msg: Message, args: string []): Promise<void> {
|
||||
|
@ -64,7 +64,7 @@ export default class implements Command {
|
|||
|
||||
await Promise.all([
|
||||
(channel as TextChannel).send('hey apparently I\'m bound to this channel now'),
|
||||
msg.react('👍')
|
||||
msg.react('👍'),
|
||||
]);
|
||||
} else {
|
||||
await msg.channel.send(errorMsg('either that channel doesn\'t exist or you want me to become sentient and listen to a voice channel'));
|
||||
|
|
|
@ -10,7 +10,7 @@ export default class implements Command {
|
|||
public name = 'disconnect';
|
||||
public aliases = ['dc'];
|
||||
public examples = [
|
||||
['disconnect', 'pauses and disconnects player']
|
||||
['disconnect', 'pauses and disconnects player'],
|
||||
];
|
||||
|
||||
public requiresVC = true;
|
||||
|
|
|
@ -11,7 +11,7 @@ export default class implements Command {
|
|||
public name = 'fseek';
|
||||
public aliases = [];
|
||||
public examples = [
|
||||
['fseek 10', 'skips forward in current song by 10 seconds']
|
||||
['fseek 10', 'skips forward in current song by 10 seconds'],
|
||||
];
|
||||
|
||||
public requiresVC = true;
|
||||
|
|
|
@ -10,7 +10,7 @@ export default class implements Command {
|
|||
public name = 'help';
|
||||
public aliases = ['h'];
|
||||
public examples = [
|
||||
['help', 'you don\'t need a description']
|
||||
['help', 'you don\'t need a description'],
|
||||
];
|
||||
|
||||
private commands: Command[] = [];
|
||||
|
|
|
@ -11,7 +11,7 @@ export default class implements Command {
|
|||
public name = 'pause';
|
||||
public aliases = [];
|
||||
public examples = [
|
||||
['pause', 'pauses currently playing song']
|
||||
['pause', 'pauses currently playing song'],
|
||||
];
|
||||
|
||||
public requiresVC = true;
|
||||
|
|
|
@ -24,7 +24,7 @@ export default class implements Command {
|
|||
['play https://open.spotify.com/album/5dv1oLETxdsYOkS2Sic00z?si=bDa7PaloRx6bMIfKdnvYQw', 'adds all songs from album to the queue'],
|
||||
['play https://open.spotify.com/playlist/37i9dQZF1DX94qaYRnkufr?si=r2fOVL_QQjGxFM5MWb84Xw', 'adds all songs from playlist to the queue'],
|
||||
['play cool music immediate', 'adds the first search result for "cool music" to the front of the queue'],
|
||||
['play cool music i', 'adds the first search result for "cool music" to the front of the queue']
|
||||
['play cool music i', 'adds the first search result for "cool music" to the front of the queue'],
|
||||
];
|
||||
|
||||
public requiresVC = true;
|
||||
|
@ -82,7 +82,7 @@ export default class implements Command {
|
|||
// YouTube source
|
||||
if (url.searchParams.get('list')) {
|
||||
// YouTube playlist
|
||||
newSongs.push(...await this.getSongs.youtubePlaylist(url.searchParams.get('list') as string));
|
||||
newSongs.push(...await this.getSongs.youtubePlaylist(url.searchParams.get('list')!));
|
||||
} else {
|
||||
// Single video
|
||||
const song = await this.getSongs.youtubeVideo(url.href);
|
||||
|
@ -135,7 +135,9 @@ export default class implements Command {
|
|||
return;
|
||||
}
|
||||
|
||||
newSongs.forEach(song => player.add({...song, addedInChannelId: msg.channel.id}, {immediate: addToFrontOfQueue}));
|
||||
newSongs.forEach(song => {
|
||||
player.add({...song, addedInChannelId: msg.channel.id}, {immediate: addToFrontOfQueue});
|
||||
});
|
||||
|
||||
const firstSong = newSongs[0];
|
||||
|
||||
|
|
|
@ -17,7 +17,7 @@ export default class implements Command {
|
|||
public aliases = ['q'];
|
||||
public examples = [
|
||||
['queue', 'shows current queue'],
|
||||
['queue 2', 'shows second page of queue']
|
||||
['queue 2', 'shows second page of queue'],
|
||||
];
|
||||
|
||||
private readonly playerManager: PlayerManager;
|
||||
|
|
|
@ -14,7 +14,7 @@ export default class implements Command {
|
|||
public examples = [
|
||||
['seek 10', 'seeks to 10 seconds from beginning of song'],
|
||||
['seek 1:30', 'seeks to 1 minute and 30 seconds from beginning of song'],
|
||||
['seek 1:00:00', 'seeks to 1 hour from beginning of song']
|
||||
['seek 1:00:00', 'seeks to 1 hour from beginning of song'],
|
||||
];
|
||||
|
||||
public requiresVC = true;
|
||||
|
|
|
@ -12,7 +12,7 @@ export default class implements Command {
|
|||
['shortcuts', 'show all shortcuts'],
|
||||
['shortcuts set s skip', 'aliases `s` to `skip`'],
|
||||
['shortcuts set party play https://www.youtube.com/watch?v=zK6oOJ1wz8k', 'aliases `party` to a specific play command'],
|
||||
['shortcuts delete party', 'removes the `party` shortcut']
|
||||
['shortcuts delete party', 'removes the `party` shortcut'],
|
||||
];
|
||||
|
||||
public async execute(msg: Message, args: string []): Promise<void> {
|
||||
|
|
|
@ -10,7 +10,7 @@ export default class implements Command {
|
|||
public name = 'shuffle';
|
||||
public aliases = [];
|
||||
public examples = [
|
||||
['shuffle', 'shuffles the current queue']
|
||||
['shuffle', 'shuffles the current queue'],
|
||||
];
|
||||
|
||||
public requiresVC = true;
|
||||
|
|
|
@ -12,7 +12,7 @@ export default class implements Command {
|
|||
public aliases = ['s'];
|
||||
public examples = [
|
||||
['skip', 'skips the current song'],
|
||||
['skip 2', 'skips the next 2 songs']
|
||||
['skip 2', 'skips the next 2 songs'],
|
||||
];
|
||||
|
||||
public requiresVC = true;
|
||||
|
|
|
@ -10,7 +10,7 @@ export default class implements Command {
|
|||
public name = 'unskip';
|
||||
public aliases = ['back'];
|
||||
public examples = [
|
||||
['unskip', 'goes back in the queue by one song']
|
||||
['unskip', 'goes back in the queue by one song'],
|
||||
];
|
||||
|
||||
public requiresVC = true;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import {Guild, TextChannel, Message} from 'discord.js';
|
||||
import {Guild, TextChannel, Message, MessageReaction, User} from 'discord.js';
|
||||
import emoji from 'node-emoji';
|
||||
import pEvent from 'p-event';
|
||||
import {Settings} from '../models/index.js';
|
||||
|
@ -31,7 +31,7 @@ export default async (guild: Guild): Promise<void> => {
|
|||
emojiChannels.push({
|
||||
name: channel.name,
|
||||
id: channelId,
|
||||
emoji: emoji.random().emoji
|
||||
emoji: emoji.random().emoji,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -52,16 +52,12 @@ export default async (guild: Guild): Promise<void> => {
|
|||
});
|
||||
|
||||
// Wait for response from user
|
||||
|
||||
const [choice] = await pEvent(guild.client, 'messageReactionAdd', {
|
||||
multiArgs: true,
|
||||
filter: options => {
|
||||
const [reaction, user] = options;
|
||||
return sentMessageIds.includes(reaction.message.id) && user.id === owner.id;
|
||||
}
|
||||
filter: ([reaction, user]: [MessageReaction, User]) => sentMessageIds.includes(reaction.message.id) && user.id === owner.id,
|
||||
});
|
||||
|
||||
const chosenChannel = emojiChannels.find(e => e.emoji === choice.emoji.name) as EmojiChannel;
|
||||
const chosenChannel = emojiChannels.find(e => e.emoji === (choice as unknown as MessageReaction).emoji.name)!;
|
||||
|
||||
// Second setup step (get prefix)
|
||||
let secondStep = `👍 Cool, I'll listen to **#${chosenChannel.name}** \n\n`;
|
||||
|
|
|
@ -30,7 +30,7 @@ import Unskip from './commands/unskip.js';
|
|||
import ThirdParty from './services/third-party.js';
|
||||
import CacheProvider from './services/cache.js';
|
||||
|
||||
let container = new Container();
|
||||
const container = new Container();
|
||||
|
||||
// Bot
|
||||
container.bind<Bot>(TYPES.Bot).to(Bot).inSingletonScope();
|
||||
|
@ -57,7 +57,7 @@ container.bind<NaturalLanguage>(TYPES.Services.NaturalLanguage).to(NaturalLangua
|
|||
Shortcuts,
|
||||
Shuffle,
|
||||
Skip,
|
||||
Unskip
|
||||
Unskip,
|
||||
].forEach(command => {
|
||||
container.bind<Command>(TYPES.Command).to(command).inSingletonScope();
|
||||
});
|
||||
|
|
|
@ -5,5 +5,5 @@ import Shortcut from './shortcut.js';
|
|||
export {
|
||||
Cache,
|
||||
Settings,
|
||||
Shortcut
|
||||
Shortcut,
|
||||
};
|
||||
|
|
|
@ -22,7 +22,7 @@ export default class CacheProvider {
|
|||
|
||||
const {
|
||||
key = JSON.stringify(functionArgs),
|
||||
expiresIn
|
||||
expiresIn,
|
||||
} = options[options.length - 1] as Options;
|
||||
|
||||
const cachedResult = await Cache.findByPk(key);
|
||||
|
@ -30,7 +30,7 @@ export default class CacheProvider {
|
|||
if (cachedResult) {
|
||||
if (new Date() < cachedResult.expiresAt) {
|
||||
debug(`Cache hit: ${key}`);
|
||||
return JSON.parse(cachedResult.value);
|
||||
return JSON.parse(cachedResult.value) as F;
|
||||
}
|
||||
|
||||
await cachedResult.destroy();
|
||||
|
@ -44,7 +44,7 @@ export default class CacheProvider {
|
|||
await Cache.upsert({
|
||||
key,
|
||||
value: JSON.stringify(result),
|
||||
expiresAt: futureTimeToDate(expiresIn)
|
||||
expiresAt: futureTimeToDate(expiresIn),
|
||||
});
|
||||
|
||||
return result;
|
||||
|
|
|
@ -11,7 +11,7 @@ const CONFIG_MAP = {
|
|||
SPOTIFY_CLIENT_ID: process.env.SPOTIFY_CLIENT_ID,
|
||||
SPOTIFY_CLIENT_SECRET: process.env.SPOTIFY_CLIENT_SECRET,
|
||||
DATA_DIR,
|
||||
CACHE_DIR: path.join(DATA_DIR, 'cache')
|
||||
CACHE_DIR: path.join(DATA_DIR, 'cache'),
|
||||
} as const;
|
||||
|
||||
@injectable()
|
||||
|
|
|
@ -42,17 +42,17 @@ export default class {
|
|||
this.ytsrQueue = new PQueue({concurrency: 4});
|
||||
}
|
||||
|
||||
async youtubeVideoSearch(query: string): Promise<QueuedSongWithoutChannel|null> {
|
||||
async youtubeVideoSearch(query: string): Promise<QueuedSongWithoutChannel | null> {
|
||||
try {
|
||||
const {items} = await this.ytsrQueue.add(async () => this.cache.wrap(
|
||||
ytsr,
|
||||
query,
|
||||
{
|
||||
limit: 10
|
||||
limit: 10,
|
||||
},
|
||||
{
|
||||
expiresIn: ONE_HOUR_IN_SECONDS
|
||||
}
|
||||
expiresIn: ONE_HOUR_IN_SECONDS,
|
||||
},
|
||||
));
|
||||
|
||||
let firstVideo: Video | undefined;
|
||||
|
@ -74,14 +74,14 @@ export default class {
|
|||
}
|
||||
}
|
||||
|
||||
async youtubeVideo(url: string): Promise<QueuedSongWithoutChannel|null> {
|
||||
async youtubeVideo(url: string): Promise<QueuedSongWithoutChannel | null> {
|
||||
try {
|
||||
const videoDetails = await this.cache.wrap(
|
||||
this.youtube.videos.get,
|
||||
cleanUrl(url),
|
||||
{
|
||||
expiresIn: ONE_HOUR_IN_SECONDS
|
||||
}
|
||||
expiresIn: ONE_HOUR_IN_SECONDS,
|
||||
},
|
||||
);
|
||||
|
||||
return {
|
||||
|
@ -90,7 +90,7 @@ export default class {
|
|||
length: toSeconds(parse(videoDetails.contentDetails.duration)),
|
||||
url: videoDetails.id,
|
||||
playlist: null,
|
||||
isLive: videoDetails.snippet.liveBroadcastContent === 'live'
|
||||
isLive: videoDetails.snippet.liveBroadcastContent === 'live',
|
||||
};
|
||||
} catch (_: unknown) {
|
||||
return null;
|
||||
|
@ -103,8 +103,8 @@ export default class {
|
|||
this.youtube.playlists.get,
|
||||
listId,
|
||||
{
|
||||
expiresIn: ONE_MINUTE_IN_SECONDS
|
||||
}
|
||||
expiresIn: ONE_MINUTE_IN_SECONDS,
|
||||
},
|
||||
);
|
||||
|
||||
interface VideoDetailsResponse {
|
||||
|
@ -128,8 +128,8 @@ export default class {
|
|||
listId,
|
||||
{maxResults: '50', pageToken: nextToken},
|
||||
{
|
||||
expiresIn: ONE_MINUTE_IN_SECONDS
|
||||
}
|
||||
expiresIn: ONE_MINUTE_IN_SECONDS,
|
||||
},
|
||||
);
|
||||
|
||||
nextToken = nextPageToken;
|
||||
|
@ -140,22 +140,20 @@ export default class {
|
|||
videoDetailsPromises.push((async () => {
|
||||
// Unfortunately, package doesn't provide a method for this
|
||||
const {items: videoDetailItems} = await this.cache.wrap(
|
||||
() => {
|
||||
return got(
|
||||
'https://www.googleapis.com/youtube/v3/videos',
|
||||
{
|
||||
searchParams: {
|
||||
part: 'contentDetails',
|
||||
id: items.map(item => item.contentDetails.videoId).join(','),
|
||||
key: this.youtubeKey,
|
||||
responseType: 'json'
|
||||
}
|
||||
}
|
||||
).json();
|
||||
},
|
||||
async () => got(
|
||||
'https://www.googleapis.com/youtube/v3/videos',
|
||||
{
|
||||
searchParams: {
|
||||
part: 'contentDetails',
|
||||
id: items.map(item => item.contentDetails.videoId).join(','),
|
||||
key: this.youtubeKey,
|
||||
responseType: 'json',
|
||||
},
|
||||
},
|
||||
).json() as Promise<{items: VideoDetailsResponse[]}>,
|
||||
{
|
||||
expiresIn: ONE_MINUTE_IN_SECONDS
|
||||
}
|
||||
expiresIn: ONE_MINUTE_IN_SECONDS,
|
||||
},
|
||||
);
|
||||
|
||||
videoDetails.push(...videoDetailItems);
|
||||
|
@ -168,9 +166,9 @@ export default class {
|
|||
|
||||
const songsToReturn: QueuedSongWithoutChannel[] = [];
|
||||
|
||||
for (let video of playlistVideos) {
|
||||
for (const video of playlistVideos) {
|
||||
try {
|
||||
const length = toSeconds(parse(videoDetails.find((i: { id: string }) => i.id === video.contentDetails.videoId)!.contentDetails.duration));
|
||||
const length = toSeconds(parse(videoDetails.find((i: {id: string}) => i.id === video.contentDetails.videoId)!.contentDetails.duration));
|
||||
|
||||
songsToReturn.push({
|
||||
title: video.snippet.title,
|
||||
|
@ -178,7 +176,7 @@ export default class {
|
|||
length,
|
||||
url: video.contentDetails.videoId,
|
||||
playlist: queuedPlaylist,
|
||||
isLive: false
|
||||
isLive: false,
|
||||
});
|
||||
} catch (_: unknown) {
|
||||
// Private and deleted videos are sometimes in playlists, duration of these is not returned and they should not be added to the queue.
|
||||
|
@ -220,7 +218,7 @@ export default class {
|
|||
// eslint-disable-next-line no-await-in-loop
|
||||
({body: tracksResponse} = await this.spotify.getPlaylistTracks(uri.id, {
|
||||
limit: parseInt(new URL(tracksResponse.next).searchParams.get('limit') ?? '50', 10),
|
||||
offset: parseInt(new URL(tracksResponse.next).searchParams.get('offset') ?? '0', 10)
|
||||
offset: parseInt(new URL(tracksResponse.next).searchParams.get('offset') ?? '0', 10),
|
||||
}));
|
||||
|
||||
tracks.push(...tracksResponse.items.map(playlistItem => playlistItem.track));
|
||||
|
|
|
@ -31,8 +31,8 @@ export default class {
|
|||
length: 204,
|
||||
playlist: null,
|
||||
isLive: false,
|
||||
addedInChannelId: msg.channel.id
|
||||
}, 8, 10)
|
||||
addedInChannelId: msg.channel.id,
|
||||
}, 8, 10),
|
||||
]);
|
||||
|
||||
return true;
|
||||
|
@ -48,8 +48,8 @@ export default class {
|
|||
length: 385,
|
||||
playlist: null,
|
||||
isLive: false,
|
||||
addedInChannelId: msg.channel.id
|
||||
}, 358, 5.5)
|
||||
addedInChannelId: msg.channel.id,
|
||||
}, 358, 5.5),
|
||||
]);
|
||||
|
||||
return true;
|
||||
|
@ -65,8 +65,8 @@ export default class {
|
|||
length: 227,
|
||||
playlist: null,
|
||||
isLive: false,
|
||||
addedInChannelId: msg.channel.id
|
||||
}, 50, 13)
|
||||
addedInChannelId: msg.channel.id,
|
||||
}, 50, 13),
|
||||
]);
|
||||
|
||||
return true;
|
||||
|
|
|
@ -26,7 +26,7 @@ export interface QueuedSong {
|
|||
|
||||
export enum STATUS {
|
||||
PLAYING,
|
||||
PAUSED
|
||||
PAUSED,
|
||||
}
|
||||
|
||||
export default class {
|
||||
|
@ -368,7 +368,7 @@ export default class {
|
|||
'-reconnect_streamed',
|
||||
'1',
|
||||
'-reconnect_delay_max',
|
||||
'5'
|
||||
'5',
|
||||
]);
|
||||
|
||||
if (options.seek) {
|
||||
|
|
|
@ -13,10 +13,11 @@ export default class ThirdParty {
|
|||
|
||||
constructor(@inject(TYPES.Config) config: Config) {
|
||||
// Library is transpiled incorrectly
|
||||
// eslint-disable-next-line
|
||||
this.youtube = new ((Youtube as any).default)(config.YOUTUBE_API_KEY);
|
||||
this.spotify = new SpotifyWebApi({
|
||||
clientId: config.SPOTIFY_CLIENT_ID,
|
||||
clientSecret: config.SPOTIFY_CLIENT_SECRET
|
||||
clientSecret: config.SPOTIFY_CLIENT_SECRET,
|
||||
});
|
||||
|
||||
void this.refreshSpotifyToken();
|
||||
|
|
|
@ -6,10 +6,10 @@ export const TYPES = {
|
|||
Command: Symbol('Command'),
|
||||
ThirdParty: Symbol('ThirdParty'),
|
||||
Managers: {
|
||||
Player: Symbol('PlayerManager')
|
||||
Player: Symbol('PlayerManager'),
|
||||
},
|
||||
Services: {
|
||||
GetSongs: Symbol('GetSongs'),
|
||||
NaturalLanguage: Symbol('NaturalLanguage')
|
||||
}
|
||||
NaturalLanguage: Symbol('NaturalLanguage'),
|
||||
},
|
||||
};
|
||||
|
|
|
@ -25,7 +25,7 @@ export const getMemberVoiceChannel = (member?: GuildMember): [VoiceChannel, numb
|
|||
if (channel && channel.type === 'voice') {
|
||||
return [
|
||||
channel,
|
||||
getSizeWithoutBots(channel)
|
||||
getSizeWithoutBots(channel),
|
||||
];
|
||||
}
|
||||
|
||||
|
@ -46,7 +46,7 @@ export const getMostPopularVoiceChannel = (guild: Guild): [VoiceChannel, number]
|
|||
|
||||
voiceChannels.push({
|
||||
channel: channel as VoiceChannel,
|
||||
n: size
|
||||
n: size,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,5 +8,5 @@ export const sequelize = new Sequelize({
|
|||
database: 'muse',
|
||||
storage: path.join(DATA_DIR, 'db.sqlite'),
|
||||
models: [Cache, Settings, Shortcut],
|
||||
logging: false
|
||||
logging: false,
|
||||
});
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue