diff --git a/autocomplete/tag.js b/autocomplete/tag.js index 98fe287..aad19e0 100644 --- a/autocomplete/tag.js +++ b/autocomplete/tag.js @@ -1,10 +1,10 @@ -const fs = require('fs') +const tag = require('../utils/tag') module.exports = { id: 'tag', async execute(interaction) { if (!['remove', 'get', 'edit'].includes(interaction.options.getSubcommand())) return - const tags = JSON.parse(fs.readFileSync('./databases/tags.json')) + const tags = tag.getAll() const tagNames = Object.keys(tags).filter(name => name.includes(interaction.options.getFocused())) return interaction.respond(tagNames.map(tag => ({ name: tag, value: tag }))) } diff --git a/commands/tag.js b/commands/tag.js index ce819cd..cb90c51 100644 --- a/commands/tag.js +++ b/commands/tag.js @@ -1,9 +1,7 @@ const { SlashCommandBuilder, ModalBuilder, TextInputBuilder, ActionRowBuilder, TextInputStyle } = require('discord.js') -const fs = require('fs') const checkUserPerms = require('../utils/checkUserPerms') const config = require('../utils/config') - -if (!fs.existsSync('./databases/tags.json')) fs.writeFileSync('./databases/tags.json', '{}') +const tag = require('../utils/tag.js') module.exports = { data: new SlashCommandBuilder() @@ -32,8 +30,6 @@ module.exports = { ), async execute(interaction) { - const tags = JSON.parse(fs.readFileSync('./databases/tags.json', 'utf-8')) - const subcommand = interaction.options.getSubcommand() if (subcommand === 'add') { if (!checkUserPerms(interaction)) { @@ -83,13 +79,12 @@ module.exports = { }) } const name = interaction.options.getString('name') - if (!tags[name]) return interaction.reply({ content: `A tag with the name ${name} does not exist.`, ephemeral: true }) + if (!tag.get(name)) return interaction.reply({ content: `A tag with the name ${name} does not exist.`, ephemeral: true }) - delete tags[name] - fs.writeFileSync('./databases/tags.json', JSON.stringify(tags, null, 4)) + tag.remove(name) interaction.reply({ content: `Removed tag ${name}.`, ephemeral: true }) } else if (subcommand === 'list') { - const tagList = Object.keys(tags) + const tagList = Object.keys(tag.getAll()) if (tagList.length === 0) return interaction.reply({ content: 'There are no tags.', ephemeral: true }) const embed = { @@ -104,7 +99,8 @@ module.exports = { } else if (subcommand === 'get') { const name = interaction.options.getString('name') const user = interaction.options.getUser('mention') - if (!tags[name]) { + const foundTag = tag.get(name) + if (!foundTag) { // Shhhh, you didn't see anything. // i certainly did not ;) // Sorry for changing this again the lack of the question mark was really getting to me! @@ -116,10 +112,10 @@ module.exports = { } const embed = { title: name, - description: tags[name].content, + description: foundTag.content, color: config.getColor('accent'), image: { - url: tags[name].image + url: foundTag.image } } user ? interaction.reply({ content: `<@${user.id}>, take a look at this!`, embeds: [embed] }) : interaction.reply({ embeds: [embed] }) @@ -131,7 +127,8 @@ module.exports = { }) } const name = interaction.options.getString('name') - if (!tags[name]) return interaction.reply({ content: `A tag with the name ${name} does not exist.`, ephemeral: true }) + const foundTag = tag.get(name) + if (!foundTag) return interaction.reply({ content: `A tag with the name ${name} does not exist.`, ephemeral: true }) const modal = new ModalBuilder().setTitle('Edit a tag').setCustomId('edit-tag') @@ -153,7 +150,7 @@ module.exports = { .setMaxLength(2000) .setRequired(true) .setStyle(TextInputStyle.Paragraph) - .setValue(tags[name].content) + .setValue(foundTag.content) const imageInput = new TextInputBuilder() .setCustomId('image') @@ -163,7 +160,7 @@ module.exports = { .setMaxLength(2000) .setStyle(TextInputStyle.Short) .setRequired(false) - .setValue(tags[name].image) + .setValue(foundTag.image) modal.addComponents(new ActionRowBuilder().addComponents(nameInput), new ActionRowBuilder().addComponents(contentInput), new ActionRowBuilder().addComponents(imageInput)) diff --git a/modals/add-tag.js b/modals/add-tag.js index 5b32686..6b5625e 100644 --- a/modals/add-tag.js +++ b/modals/add-tag.js @@ -1,21 +1,14 @@ -const fs = require('fs') - -if (!fs.existsSync('./databases/tags.json')) fs.writeFileSync('./databases/tags.json', '{}') +const tag = require('../utils/tag') module.exports = { id: 'add-tag', async execute(interaction) { - const tags = JSON.parse(fs.readFileSync('./databases/tags.json', 'utf-8')) const name = interaction.fields.fields.find(f => f.customId === 'name').value const content = interaction.fields.fields.find(f => f.customId === 'content').value const image = interaction.fields.fields.find(f => f.customId === 'image').value - if (tags[name]) return interaction.reply({ content: `A tag with the name ${name} already exists.`, ephemeral: true }) + if (tag.get(name)) return interaction.reply({ content: `A tag with the name ${name} already exists.`, ephemeral: true }) - tags[name] = { - content, - image - } - fs.writeFileSync('./databases/tags.json', JSON.stringify(tags, null, 4)) + tag.add(name, content, image) interaction.reply({ content: `Added tag ${name}.`, ephemeral: true }) } } diff --git a/modals/edit-tag.js b/modals/edit-tag.js index 0a0e137..3bdd264 100644 --- a/modals/edit-tag.js +++ b/modals/edit-tag.js @@ -1,21 +1,14 @@ -const fs = require('fs') - -if (!fs.existsSync('./databases/tags.json')) fs.writeFileSync('./databases/tags.json', '{}') +const tag = require('../utils/tag') module.exports = { id: 'edit-tag', async execute(interaction) { - const tags = JSON.parse(fs.readFileSync('./databases/tags.json', 'utf-8')) const name = interaction.fields.fields.find(f => f.customId === 'name').value const content = interaction.fields.fields.find(f => f.customId === 'content').value const image = interaction.fields.fields.find(f => f.customId === 'image').value - if (!tags[name]) return interaction.reply({ content: `A tag with the name ${name} does not exist.`, ephemeral: true }) + if (!tag.get(name)) return interaction.reply({ content: `A tag with the name ${name} does not exist.`, ephemeral: true }) - tags[name] = { - content, - image - } - fs.writeFileSync('./databases/tags.json', JSON.stringify(tags, null, 4)) + tag.modify(name, content, image) interaction.reply({ content: `Edited tag ${name}.`, ephemeral: true }) } } diff --git a/utils/tag.js b/utils/tag.js new file mode 100644 index 0000000..f0bed42 --- /dev/null +++ b/utils/tag.js @@ -0,0 +1,61 @@ +const fs = require('fs') + +function ensureDatabase() { + const exists = fs.existsSync('./databases/tags.json') + if (!exists) fs.writeFileSync('./databases/tags.json', '[]') + try { + JSON.parse(fs.readFileSync('./databases/tags.json')) + } catch { + fs.writeFileSync('./databases/tags.bak.json', fs.readFileSync('./databases/tags.json')) + console.log('Your tags database was corrupted, so we had to reset it. You can find a backup in ./databases/tags.bak.json') + fs.writeFileSync('./databases/tags.json', '[]') + } +} + +function writeDatabase(data) { + ensureDatabase() + fs.writeFileSync('./databases/tags.json', JSON.stringify(data)) +} + +function getDatabase() { + ensureDatabase() + return JSON.parse(fs.readFileSync('./databases/tags.json')) +} + +module.exports = { + add: async (name, content, image) => { + ensureDatabase() + const database = getDatabase() + if (database[name]) return + database[name] = { + name, + content, + image + } + writeDatabase(database) + }, + remove: name => { + ensureDatabase() + const database = getDatabase() + delete database[name] + writeDatabase(database) + }, + modify: (name, content, image) => { + ensureDatabase() + const database = getDatabase() + if (!database[name]) database[name] = {} + const item = database[name] + item.name = name || item.name + item.content = content || item.content + item.image = image || item.image + writeDatabase(database) + }, + get: name => { + ensureDatabase() + return getDatabase()[name] + }, + getAll: () => { + ensureDatabase() + return getDatabase() + } +}