Skip to content

Add gif command #4

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Apr 20, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
108 changes: 108 additions & 0 deletions src/commands/gif/index.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
import { generateGifEmbed } from '.';
import { WaifuSchema } from '../../schemas/waifu';

const props: WaifuSchema = {
signature: 'a signature',
extension: 'an extension',
image_id: 1,
favorites: 100,
dominant_color: 'a color',
source: 'a source',
uploaded_at: 'uploaded sometime',
liked_at: null,
is_nsfw: false,
width: 100,
height: 200,
byte_size: 20,
url: 'a url',
preview_url: 'a preview',
tags: [
{
tag_id: 1,
name: 'a tag',
description: 'a description',
is_nsfw: false,
},
],
};

describe('Gif Command', () => {
it('generates an embed correctly', () => {
const embed = generateGifEmbed(props);

expect(embed).not.toBeUndefined();
});
it('displays the correct fields in the embed', () => {
const embed = generateGifEmbed(props);

expect(embed.description).not.toBeUndefined();
expect(embed.color).not.toBeUndefined();
expect(embed.fields).not.toBeUndefined();
expect(embed.fields && embed.fields.length).toBe(2);
});
it('shows the correct color in the embed', () => {
const embed = generateGifEmbed({ ...props, dominant_color: '#800000' });

expect(embed.color).not.toBeUndefined();
expect(embed.color).toBe(8388608);
});
it('shows the correct tags in the embed if there are no tags', () => {
const embed = generateGifEmbed({ ...props, tags: [] });

expect(embed.fields).not.toBeUndefined();
expect(embed.fields && embed.fields[1].name).toBe('Tags');
expect(embed.fields && embed.fields[1].value).toBe('');
});
it('shows the correct tags in the embed if there is only one tag', () => {
const tags = [
{
tag_id: 1,
name: 'waifu',
description: 'a description',
is_nsfw: false,
},
];
const embed = generateGifEmbed({ ...props, tags });

expect(embed.fields).not.toBeUndefined();
expect(embed.fields && embed.fields[1].name).toBe('Tags');
expect(embed.fields && embed.fields[1].value.includes(',')).toBe(false);
expect(embed.fields && embed.fields[1].value).toBe('waifu');
});
it('shows the correct tags in the embed if there are a couple of tags', () => {
const tags = [
{
tag_id: 1,
name: 'waifu',
description: 'a description',
is_nsfw: false,
},
{
tag_id: 2,
name: 'uniform',
description: 'a description',
is_nsfw: false,
},
];
const embed = generateGifEmbed({ ...props, tags });

expect(embed.fields).not.toBeUndefined();
expect(embed.fields && embed.fields[1].name).toBe('Tags');
expect(embed.fields && embed.fields[1].value.includes(',')).toBe(true);
expect(embed.fields && embed.fields[1].value).toBe('waifu, uniform');
});
it('shows the correct orientation if width is larger than height', () => {
const embed = generateGifEmbed({ ...props, width: 1200, height: 1000 });

expect(embed.fields).not.toBeUndefined();
expect(embed.fields && embed.fields[0].name).toBe('Orientation');
expect(embed.fields && embed.fields[0].value).toBe('Landscape');
});
it('shows the correct orientation if height is larger than width', () => {
const embed = generateGifEmbed({ ...props, width: 1000, height: 1200 });

expect(embed.fields).not.toBeUndefined();
expect(embed.fields && embed.fields[0].name).toBe('Orientation');
expect(embed.fields && embed.fields[0].value).toBe('Portrait');
});
});
53 changes: 53 additions & 0 deletions src/commands/gif/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
import { APIEmbed, hyperlink, SlashCommandBuilder } from 'discord.js';
import { isEmpty, reduce } from 'lodash';
import { WaifuSchema } from '../../schemas/waifu';
import { getWaifu } from '../../services/adapters';
import { sendErrorLog } from '../../utils/helpers';
import { AppCommand, AppCommandOptions } from '../commands';

export const generateGifEmbed = (data: WaifuSchema): APIEmbed => {
const color = parseInt(data.dominant_color.replace('#', '0x'));
const tags = reduce(
data.tags,
(accumulator, value) => {
return `${accumulator}${isEmpty(accumulator) ? '' : ', '}${value.name}`;
},
''
);
const orientation: 'Portrait' | 'Landscape' = data.width > data.height ? 'Landscape' : 'Portrait';
const embed: APIEmbed = {
color,
description: `${hyperlink('Source', data.source)} | ${hyperlink('Preview', data.preview_url)}`,
image: {
url: data.url,
},
fields: [
{
name: 'Orientation',
value: orientation,
inline: true,
},
{
name: 'Tags',
value: tags,
inline: true,
},
],
};
return embed;
};

export default {
commandType: 'Waifu',
data: new SlashCommandBuilder().setName('gif').setDescription('Shows a random waifu gif'),
async execute({ interaction }: AppCommandOptions) {
try {
await interaction.deferReply();
const data = await getWaifu({ isGif: true });
const embed = generateGifEmbed(data);
await interaction.editReply({ embeds: [embed] });
} catch (error) {
sendErrorLog({ error, interaction });
}
},
} as AppCommand;
8 changes: 6 additions & 2 deletions src/services/adapters.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,13 @@ import { WaifuAPI, WaifuSchema } from '../schemas/waifu';

const BASE_URL = 'https://api.waifu.im';

export async function getWaifu(): Promise<WaifuSchema> {
interface WaifuProps {
isGif?: boolean;
}

export async function getWaifu(props?: WaifuProps): Promise<WaifuSchema> {
const response = (await got
.get(`${BASE_URL}/search?orientation=RANDOM&is_nsfw=FALSE`)
.get(`${BASE_URL}/search?orientation=RANDOM&is_nsfw=false&gif=${props ? props.isGif : false}`)
.json()) as WaifuAPI;
return response.images[0];
}