Skip to content

Commit

Permalink
Merge pull request #469 from gowon-bot/ferry-changes
Browse files Browse the repository at this point in the history
Improve custom album covers and emoji parsing
  • Loading branch information
abbyfour authored Nov 28, 2023
2 parents 765bbc2 + 019b3df commit ad75a3f
Show file tree
Hide file tree
Showing 20 changed files with 371 additions and 153 deletions.
1 change: 1 addition & 0 deletions config.example.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
"discordToken": "Get this from the discord developer portal",
"discordClientID": "Get this from the discord developer portal",
"slashCommandTestGuildID": "If environment = development, it will register slash commands to this guild instead of globally",
"emojiVerificationChannelId": "The channel which Gowon will use to verify emojis are accessible to the bot",

"defaultPrefix": "!",

Expand Down
4 changes: 3 additions & 1 deletion src/commands/Lastfm/Cover.ts
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,9 @@ export default class Cover extends LastFMBaseCommand<typeof args> {
files: [
{
attachment: albumCover.url,
name: `${artist} - ${album}.${albumCover.fileExtension}`,
name: albumCover.fileExtension
? `${artist} - ${album}.${albumCover.fileExtension}`
: undefined,
description: `The album cover for ${album} by ${artist}`,
},
],
Expand Down
4 changes: 2 additions & 2 deletions src/commands/Lastfm/NowPlaying/Config/React.ts
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ export class React extends NowPlayingConfigChildCommand<typeof args> {
}

private async saveReacts(emojis: EmojiMention[]) {
const { valid, invalid } = this.emojiService.validateEmojis(
const { valid, invalid } = await this.emojiService.validateEmojis(
this.ctx,
emojis
);
Expand Down Expand Up @@ -135,7 +135,7 @@ export class React extends NowPlayingConfigChildCommand<typeof args> {

if (invalid.length) {
embed.setFooter({
text: "Gowon needs to share a server with an emoji to be able to react with it\nRecently-added emojis may take a little while for Gowon to be able to recognize",
text: "Gowon needs to share a server with an emoji to be able to react with it",
});
}

Expand Down
2 changes: 1 addition & 1 deletion src/commands/Lastfm/NowPlaying/FakeNowPlaying.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ const args = {
export default class FakeNowPlaying extends NowPlayingBaseCommand<typeof args> {
idSeed = "april jinsol";

aliases = ["track"];
aliases = ["track", "fnp", "ffm"];

arguments = args;

Expand Down
27 changes: 12 additions & 15 deletions src/commands/Lastfm/Spotify/Playlists/Add.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
import { LogicError } from "../../../../errors/errors";
import {
CouldNotFindPlaylistWithTagError,
CouldNotFindTrackToChangePlaylistError,
} from "../../../../errors/external/spotify";
import { bold, italic } from "../../../../helpers/discord";
import { Variation } from "../../../../lib/command/Command";
import { EmojisArgument } from "../../../../lib/context/arguments/argumentTypes/discord/EmojisArgument";
import { StringArgument } from "../../../../lib/context/arguments/argumentTypes/StringArgument";
import { removeEmojisFromString } from "../../../../lib/context/arguments/parsers/EmojiParser";
import { EmojiParser } from "../../../../lib/context/arguments/parsers/EmojiParser";
import { ArgumentsMap } from "../../../../lib/context/arguments/types";
import { PlaylistChildCommand } from "./PlaylistChildCommand";

Expand All @@ -15,16 +18,16 @@ const args = {
artist: new StringArgument({
index: 0,
splitOn: "|",
preprocessor: removeEmojisFromString,
preprocessor: EmojiParser.removeEmojisFromString,
description: "That artist of the track you want to add",
}),
track: new StringArgument({
index: 1,
splitOn: "|",
preprocessor: removeEmojisFromString,
preprocessor: EmojiParser.removeEmojisFromString,
description: "That track of the track you want to add",
}),
} satisfies ArgumentsMap
} satisfies ArgumentsMap;

export class Add extends PlaylistChildCommand<typeof args> {
idSeed = "pink fantasy harin";
Expand Down Expand Up @@ -58,11 +61,7 @@ export class Add extends PlaylistChildCommand<typeof args> {
);

if (!playlistTag) {
throw new LogicError(
emoji
? `Couldn't find a playlist tagged with ${emoji.resolvable}!`
: `Couldn't find a default playlist! (Set one with \`${this.prefix}pl default\`)`
);
throw new CouldNotFindPlaylistWithTagError(this.prefix, emoji);
}

const { track, askedConfirmation } = await this.spotifyArguments.getTrack(
Expand All @@ -74,10 +73,7 @@ export class Add extends PlaylistChildCommand<typeof args> {
if (!track) {
if (askedConfirmation) return;

throw new LogicError(
`Couldn't find a track to ${remove ? "remove from" : "add to"
} a playlist!`
);
throw new CouldNotFindTrackToChangePlaylistError(remove);
}

await this.spotifyService[remove ? "removeFromPlaylist" : "addToPlaylist"](
Expand All @@ -93,7 +89,8 @@ export class Add extends PlaylistChildCommand<typeof args> {
)
)
.setDescription(
`Successfully ${remove ? "removed" : "added"} ${italic(track.name)} ${remove ? "from" : "to"
`Successfully ${remove ? "removed" : "added"} ${italic(track.name)} ${
remove ? "from" : "to"
} ${bold(playlistTag.playlistName)}`
)
.setThumbnail(track.album.images.largest.url);
Expand Down
10 changes: 5 additions & 5 deletions src/commands/Lastfm/Spotify/Playlists/Tag.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { LogicError } from "../../../../errors/errors";
import { PlaylistNotFoundError } from "../../../../errors/external/spotify";
import { bold } from "../../../../helpers/discord";
import { EmojisArgument } from "../../../../lib/context/arguments/argumentTypes/discord/EmojisArgument";
import { StringArgument } from "../../../../lib/context/arguments/argumentTypes/StringArgument";
import { removeEmojisFromString } from "../../../../lib/context/arguments/parsers/EmojiParser";
import { EmojiParser } from "../../../../lib/context/arguments/parsers/EmojiParser";
import { ArgumentsMap } from "../../../../lib/context/arguments/types";
import { Validation } from "../../../../lib/validation/ValidationChecker";
import { validators } from "../../../../lib/validation/validators";
Expand All @@ -15,12 +15,12 @@ const args = {
required: true,
}),
playlist: new StringArgument({
preprocessor: removeEmojisFromString,
preprocessor: EmojiParser.removeEmojisFromString,
required: true,
description: "The name of the playlist to tag",
index: { start: 0 },
}),
} satisfies ArgumentsMap
} satisfies ArgumentsMap;

export class Tag extends PlaylistChildCommand<typeof args> {
idSeed = "pink fantasy momoka";
Expand Down Expand Up @@ -56,7 +56,7 @@ export class Tag extends PlaylistChildCommand<typeof args> {
);

if (!foundPlaylist) {
throw new LogicError(`Couldn't find a playlist with that name!`);
throw new PlaylistNotFoundError();
}

await this.spotifyPlaylistTagService.tagPlaylist(this.ctx, dbUser, {
Expand Down
40 changes: 29 additions & 11 deletions src/commands/Moderation/content/SetAlbumCover.ts
Original file line number Diff line number Diff line change
@@ -1,22 +1,37 @@
import { MustBeAPatronError } from "../../../errors/commands/permissions";
import { bold, italic } from "../../../helpers/discord";
import { Flag } from "../../../lib/context/arguments/argumentTypes/Flag";
import { ImageArgument } from "../../../lib/context/arguments/argumentTypes/ImageArgument";
import { StringArgument } from "../../../lib/context/arguments/argumentTypes/StringArgument";
import { prefabArguments } from "../../../lib/context/arguments/prefabArguments";
import { URLParser } from "../../../lib/context/arguments/parsers/URLParser";
import { ArgumentsMap } from "../../../lib/context/arguments/types";
import { ArgumentValidationError } from "../../../lib/validation/validators/BaseValidator";
import { ConfirmationEmbed } from "../../../lib/views/embeds/ConfirmationEmbed";
import { LastFMArguments } from "../../../services/LastFM/LastFMArguments";
import { AlbumCoverService } from "../../../services/moderation/AlbumCoverService";
import { ServiceRegistry } from "../../../services/ServicesRegistry";
import { ContentModerationCommand } from "./ContentModerationCommand";

const args = {
...prefabArguments.album,
url: new StringArgument({
artist: new StringArgument({
splitOn: "|",
description:
"The artist to use (defaults to your currently playing artist)",
preprocessor: URLParser.removeURLsFromString,
}),
album: new StringArgument({
splitOn: "|",
index: 1,
description: "The album to use (defaults to your currently playing album)",
preprocessor: URLParser.removeURLsFromString,
}),
clear: new StringArgument({
splitOn: "|",
index: 2,
description: "The url to set as the alternate",
required: true,
preprocessor: URLParser.removeURLsFromString,
}),
image: new ImageArgument({
description: "The image to set as the alternate (URL or file upload)",
}),
moderation: new Flag({
description: "Replace an album cover bot wide (content moderators only)",
Expand Down Expand Up @@ -44,6 +59,13 @@ export default class SetAlbumCover extends ContentModerationCommand<
albumCoverService = ServiceRegistry.get(AlbumCoverService);

async run() {
const image = (this.parsedArguments.image || [])[0],
shouldClear = this.parsedArguments.clear === "clear";

if (!shouldClear && !image) {
throw new ArgumentValidationError(`Please enter an image!`);
}

const { dbUser, requestable } = await this.getMentions({
senderRequired: true,
});
Expand All @@ -62,8 +84,6 @@ export default class SetAlbumCover extends ContentModerationCommand<
{ redirect: true }
);

const shouldClear = this.parsedArguments.url === "clear";

const existingCover = await this.albumCoverService.getAlternateCover(
this.ctx,
artist,
Expand All @@ -88,7 +108,7 @@ This will ${shouldClear ? "clear" : "set"} the image ${bold(
this.parsedArguments.moderation ? "bot-wide" : "for you only"
)}.`
)
.setImage(!shouldClear ? this.parsedArguments.url : "")
.setImage(!shouldClear ? image.asURL() : "")
.setThumbnail(existingCover?.url || "");

const confirmationEmbed = new ConfirmationEmbed(
Expand All @@ -113,9 +133,7 @@ This will ${shouldClear ? "clear" : "set"} the image ${bold(
} else {
await this.albumCoverService.setAlternate(
this.ctx,
artist,
album,
this.parsedArguments.url,
image.withMetadata({ artist, album }),
user
);
}
Expand Down
12 changes: 10 additions & 2 deletions src/database/entity/AlternateAlbumCover.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
import {
Entity,
PrimaryGeneratedColumn,
BaseEntity,
Column,
Entity,
JoinColumn,
ManyToOne,
PrimaryGeneratedColumn,
} from "typeorm";
import { Image } from "../../lib/views/Image";
import { User } from "./User";

@Entity({ name: "alternate_album_covers" })
Expand All @@ -29,4 +30,11 @@ export class AlternateAlbumCover extends BaseEntity {
public get setByModerator(): boolean {
return !this.user;
}

public get image(): Image {
return new Image({
url: this.url,
metadata: { artist: this.artistName, album: this.albumName },
});
}
}
33 changes: 33 additions & 0 deletions src/errors/external/spotify.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { EmojiMention } from "../../lib/context/arguments/parsers/EmojiParser";
import { ClientError, ClientWarning } from "../errors";

export class SpotifyConnectionError extends ClientError {
Expand Down Expand Up @@ -68,3 +69,35 @@ export class PrivateModeOnWarning extends ClientWarning {
);
}
}

export class PlaylistNotFoundError extends ClientError {
name = "PlaylistNotFoundError";

constructor() {
super(`Couldn't find a playlist with that name!`);
}
}

export class CouldNotFindPlaylistWithTagError extends ClientError {
name = "CouldNotFindPlaylistWithTagError";

constructor(prefix: string, emoji: EmojiMention | undefined) {
super(
emoji
? `Couldn't find a playlist tagged with ${emoji.resolvable}!`
: `Couldn't find a default playlist! (Set one with \`${prefix}pl default\`)`
);
}
}

export class CouldNotFindTrackToChangePlaylistError extends ClientError {
name = "CouldNotFindTrackToChangePlaylistError";

constructor(isRemove?: boolean) {
super(
`Couldn't find a track to ${
isRemove ? "remove from" : "add to"
} a playlist!`
);
}
}
6 changes: 0 additions & 6 deletions src/helpers/error.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,3 @@ export function parseError(error: RawLastFMErrorResponse): string {
return error.message;
}
}

export function silentFail(func: () => any) {
try {
func();
} catch {}
}
15 changes: 5 additions & 10 deletions src/lib/command/Command.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ import config from "../../../config.json";
import { AnalyticsCollector } from "../../analytics/AnalyticsCollector";
import { ClientError, UnknownError } from "../../errors/errors";
import { GuildRequiredError } from "../../errors/gowon";
import { silentFail } from "../../helpers/error";
import { SimpleMap } from "../../helpers/types";
import { DiscordService } from "../../services/Discord/DiscordService";
import {
Expand Down Expand Up @@ -535,15 +534,11 @@ export abstract class Command<ArgumentsType extends ArgumentsMap = {}> {
);

if (senderUser) {
silentFail(() => this.lilacUsersService.update(this.ctx, senderUser));

try {
await this.lilacGuildsService.addUser(
this.ctx,
this.author.id,
this.requiredGuild.id
);
} catch (e) {}
this.lilacUsersService.update(this.ctx, senderUser).catch(() => {});

this.lilacGuildsService
.addUser(this.ctx, this.author.id, this.requiredGuild.id)
.catch(() => {});
}
}
}
Expand Down
Loading

0 comments on commit ad75a3f

Please sign in to comment.