diff --git a/.gitignore b/.gitignore index 79b52548..48eca72f 100644 --- a/.gitignore +++ b/.gitignore @@ -7,6 +7,9 @@ logs/ *.log report*.json +# Temp Files +tmp/ + # Config Files .env config.json @@ -17,6 +20,9 @@ blacklist.json # Tensorflow Models tf_models/ +# DECTalk Files +dectalk/ + # Tesseract Trained Data *.traineddata diff --git a/README.md b/README.md index 9d0eb9e7..fa990e82 100644 --- a/README.md +++ b/README.md @@ -37,9 +37,10 @@ luck on this one. 3. [Install ImageMagick](https://imagemagick.org/script/download.php). 4. [Follow these instructions to install Redis](https://riptutorial.com/redis/example/29962/installing-and-running-redis-server-on-windows). Remember to set up a password! 5. Download [the NSFW model](https://github.com/gantman/nsfw_model) and extract the contents to `/tf_models/nsfw`. -6. Run `npm i --production` in the folder you cloned the bot. -7. Run `npm i -g pm2` to install PM2. -8. Run `pm2 start Xiao.js --name xiao` to run the bot. +6. Download DECTalk and extract it to `/dectalk`. You will have to find this yourself. You need the files `say.exe`, `dectalk.dll`, and `dtalk_us.dic`. +7. Run `npm i --production` in the folder you cloned the bot. +8. Run `npm i -g pm2` to install PM2. +9. Run `pm2 start Xiao.js --name xiao` to run the bot. ### Mac @@ -59,6 +60,12 @@ luck on this one. 8. [Follow these instructions to set up Redis](https://www.digitalocean.com/community/tutorials/how-to-install-and-secure-redis-on-ubuntu-18-04). Remember to set up a password! 9. Run `apt install libtool` so sodium can compile if necessary. **(Optional)** 10. Download [the NSFW model](https://github.com/gantman/nsfw_model) and extract the contents to `/tf_models/nsfw`. -11. Run `npm i --production` in the folder you cloned the bot. -12. Run `npm i -g pm2` to install PM2. -13. Run `pm2 start Xiao.js --name xiao` to run the bot. +11. Download DECTalk and extract it to `/dectalk`. You will have to find this yourself. You need the files `say.exe`, `dectalk.dll`, and `dtalk_us.dic`. +12. Run `apt install wine` to install wine. +13. Run `dpkg --add-architecture i386` to allow installation of `wine32`. +14. Run `apt update` again. +15. Run `apt install wine32` to install wine32. +16. Run `apt install xvfb` to install xvfb. +17. Run `npm i --production` in the folder you cloned the bot. +18. Run `npm i -g pm2` to install PM2. +19. Run `pm2 start Xiao.js --name xiao` to run the bot. diff --git a/commands/util/exec.js b/commands/util/exec.js index 2f3f5aff..e1ae432a 100644 --- a/commands/util/exec.js +++ b/commands/util/exec.js @@ -1,5 +1,7 @@ const Command = require('../../structures/Command'); -const { execSync } = require('child_process'); +const { exec } = require('child_process'); +const { promisify } = require('util'); +const execAsync = promisify(exec); const { stripIndents } = require('common-tags'); const { XIAO_GITHUB_REPO_USERNAME, XIAO_GITHUB_REPO_NAME, GITHUB_ACCESS_TOKEN } = process.env; @@ -23,12 +25,12 @@ module.exports = class ExecCommand extends Command { }); } - run(msg, { command }) { + async run(msg, { command }) { if (command === 'git pull') { const repo = `${XIAO_GITHUB_REPO_USERNAME}/${XIAO_GITHUB_REPO_NAME}`; command = `git pull https://${GITHUB_ACCESS_TOKEN}@github.com/${repo}.git`; } - const results = this.exec(command); + const results = await this.exec(command); return msg.reply(stripIndents` _${results.err ? 'An error occurred:' : 'Successfully executed.'}_ \`\`\`sh @@ -37,9 +39,9 @@ module.exports = class ExecCommand extends Command { `); } - exec(command) { + async exec(command) { try { - const stdout = execSync(command, { timeout: 30000, encoding: 'utf8' }); + const stdout = await execAsync(command, { timeout: 30000, encoding: 'utf8' }); return { err: false, std: stdout.trim() }; } catch (err) { return { err: true, std: err.stderr.trim() }; diff --git a/commands/voice/dec-talk.js b/commands/voice/dec-talk.js index 6462f897..11abaf35 100644 --- a/commands/voice/dec-talk.js +++ b/commands/voice/dec-talk.js @@ -1,6 +1,10 @@ const Command = require('../../structures/Command'); -const request = require('node-superfetch'); const { Readable } = require('stream'); +const { exec } = require('child_process'); +const { promisify } = require('util'); +const execAsync = promisify(exec); +const { writeFile, unlink, readFile } = require('fs/promises'); +const path = require('path'); const { reactIfAble } = require('../../util/Util'); const { LOADING_EMOJI_ID } = process.env; @@ -19,12 +23,6 @@ module.exports = class DECTalkCommand extends Command { }, userPermissions: ['CONNECT', 'SPEAK'], credit: [ - { - name: 'calzoneman', - url: 'https://github.com/calzoneman', - reason: 'API', - reasonURL: 'https://github.com/calzoneman/aeiou' - }, { name: 'Digital Equipment Corporation', url: 'http://gordonbell.azurewebsites.net/digital/timeline/tmlnhome.htm', @@ -57,9 +55,7 @@ module.exports = class DECTalkCommand extends Command { if (this.client.dispatchers.has(msg.guild.id)) return msg.reply('I am already playing audio in this server.'); try { await reactIfAble(msg, this.client.user, LOADING_EMOJI_ID, '💬'); - const { body } = await request - .get('http://tts.cyzon.us/tts') - .query({ text }); + const body = await this.tts(msg.guild.id, text); const dispatcher = connection.play(Readable.from([body])); this.client.dispatchers.set(msg.guild.id, dispatcher); dispatcher.once('finish', () => this.client.dispatchers.delete(msg.guild.id)); @@ -71,4 +67,21 @@ module.exports = class DECTalkCommand extends Command { return msg.reply(`Oh no, an error occurred: \`${err.message}\`. Try again later!`); } } + + async tts(id, input) { + await writeFile(path.join(__dirname, '..', '..', 'tmp', `${id}.txt`), input); + await execAsync(`xvfb-run wine say.exe -w ${id}.wav < ${path.join(__dirname, '..', '..', 'tmp', `${id}.txt`)}`, { + cwd: path.join(__dirname, '..', '..', 'dectalk'), + timeout: 30000 + }); + let result; + try { + result = await readFile(path.join(__dirname, '..', '..', 'tmp', `${id}.wav`)); + await unlink(path.join(__dirname, '..', '..', 'tmp', `${id}.txt`)); + await unlink(path.join(__dirname, '..', '..', 'tmp', `${id}.wav`)); + } catch { + if (!result) result = null; + } + return result; + } }; diff --git a/package.json b/package.json index a4f9071b..f557937b 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "xiao", - "version": "134.6.0", + "version": "134.6.1", "description": "Your personal server companion.", "main": "Xiao.js", "private": true,