diff --git a/src/DiscordBot.js b/src/DiscordBot.js new file mode 100644 index 0000000..5805e0f --- /dev/null +++ b/src/DiscordBot.js @@ -0,0 +1,104 @@ +require('dotenv').config({path:'../.env'}); + +const fs = require('fs'), + discord = require("discord.js"), + { Collection, Intents } = require('discord.js'), + { promisify } = require('util'); + +class DiscordBot { + constructor() { + this.guild = null; + this.twitchBadge = null; + + this.client = new discord.Client({ + intents: [ + Intents.FLAGS.GUILDS, + Intents.FLAGS.GUILD_MEMBERS, + Intents.FLAGS.GUILD_BANS, + Intents.FLAGS.GUILD_EMOJIS_AND_STICKERS, + Intents.FLAGS.GUILD_INTEGRATIONS, + Intents.FLAGS.GUILD_WEBHOOKS, + Intents.FLAGS.GUILD_INVITES, + Intents.FLAGS.GUILD_VOICE_STATES, + Intents.FLAGS.GUILD_PRESENCES, + Intents.FLAGS.GUILD_MESSAGES, + Intents.FLAGS.GUILD_MESSAGE_REACTIONS, + Intents.FLAGS.GUILD_MESSAGE_TYPING, + Intents.FLAGS.DIRECT_MESSAGES, + Intents.FLAGS.DIRECT_MESSAGE_REACTIONS, + Intents.FLAGS.DIRECT_MESSAGE_TYPING, + ] + }); + + + // commands + this.client.commands = new Collection(); + + const commandFiles = fs.readdirSync("./discord/commands").filter((file) => file.endsWith(".js")); + + for (const file of commandFiles) { + const command = require(`./discord/commands/${file}`); + this.client.commands.set(command.data.name, command); + } + + // events + const eventFiles = fs.readdirSync('./discord/events').filter(file => file.endsWith('.js')); + + for (const file of eventFiles) { + const event = require(`./discord/events/${file}`); + if (event.once) { + this.client.once(event.name, (...args) => event.execute(this.client,...args)); + } else { + this.client.on(event.name, (...args) => event.execute(this.client,...args)); + } + } + } + start() { + this.client.login(process.env.DISCORD_TOKEN) + .catch(console.error); + } + restart() { + console.log('restarting...') + this.client.destroy() + .then(() => { + this.start(); + }); + } + // update stream-notification channel + updateStreamNotificationChannel(channel) { + + } + sendMessage(channelId, message) { + const channel = this.guild.channels.cache.get(channelId); + channel.send(message); + + } + liveNotification(channelId, streamer) { + const channel = this.guild.channels.cache.get(channelId), + message = `Hey @everyone, <@${streamer.discordId}> has gone live on Twitch Watch them here: \n` + + `https://www.twitch.tv/${streamer.twitchName}`; + channel.send(message); + + } + liveEmbed(rank, streamers) { + const channel = this.guild.channels.cache.get(rank.channelId); + if(!rank.messageId) { + const embed = generateEmbed(rank,streamers); + channel.send(embed); + rank.messageId = embed.id; + } + else { + rank.messageId.edit(generateEmbed(rank,streamers)) + } + // check if bot sent a message before + // if yes, update it + // else, create a new one + } + // update stats channels + // update featured + // update levels + // backup + // logs +} + +module.exports = { DiscordBot }; \ No newline at end of file diff --git a/src/TwitchBot.js b/src/TwitchBot.js new file mode 100644 index 0000000..9f79aad --- /dev/null +++ b/src/TwitchBot.js @@ -0,0 +1,77 @@ +require('dotenv').config({path:'../.env'}); + +const fs = require('fs'), + tmi = require('tmi.js'), + { Collection } = require('discord.js'); + +class TwitchBot { + constructor(channels) { + console.log(channels) + this.client = new tmi.Client({ + options: { + debug: true, + messagesLogLevel: "info" + }, + connection: { + reconnect: true, + secure: true + }, + identity: { + username: `${process.env.TWITCH_BOT_USERNAME}`, + password: `oauth:${process.env.TWITCH_ACCESS_TOKEN}` + }, + channels + }); + + // commands + this.client.commands = new Collection(); + + const commandFiles = fs.readdirSync("./twitch/commands").filter((file) => file.endsWith(".js")); + + for (const file of commandFiles) { + const command = require(`./twitch/commands/${file}`); + this.client.commands.set(command.name, command); + } + + // events + const eventFiles = fs.readdirSync('./twitch/events').filter(file => file.endsWith('.js')); + + for (const file of eventFiles) { + const event = require(`./twitch/events/${file}`); + if (event.once) { + this.client.once(event.name, (...args) => event.execute(this.client,...args)); + } else { + this.client.on(event.name, (...args) => event.execute(this.client,...args)); + } + } + } + start() { + console.log('starting...') + this.client.connect().catch(err => console.log(err)); + } + disconnect() { + console.log('disconnecting...') + this.client.disconnect() + .then((data) => { + // data returns [server, port] + }).catch(err => console.log(err)); + } + restart(){ + console.log('restarting...') + this.client.disconnect().catch(err => console.log(err)); + this.start(); + } + join(channel) { + this.client.join(channel).catch(err => console.log(err)); + } + leave(channel) { + this.client.part(channel).catch(err => console.log(err)); + } + host(channel, target) { + this.client.host(channel, target).catch(err => console.log(err)); + } + // TODO: to verify a user, send a message to whisper + +} + +module.exports = { TwitchBot }; \ No newline at end of file diff --git a/src/ai/ArcaneGAN/main.py b/src/ai/ArcaneGAN/main.py index 68d8ad8..4f77b5a 100644 --- a/src/ai/ArcaneGAN/main.py +++ b/src/ai/ArcaneGAN/main.py @@ -117,7 +117,7 @@ def process(output_path,mtcnn,model,img): args = parser.parse_args() project_path = "/home/alotaima/Projects/side/onlysudo/src/ai/ArcaneGAN" - args.outdir = '/src/api/public/ai/arcane' + args.outdir = '/src/server/public/ai/arcane' args.size = 1024 if args.url == '': diff --git a/src/ai/BlendGAN/main.py b/src/ai/BlendGAN/main.py index df1dc6b..a4ed97f 100644 --- a/src/ai/BlendGAN/main.py +++ b/src/ai/BlendGAN/main.py @@ -40,8 +40,8 @@ args.ckpt = f'{project_path}/pretrained_models/blendgan.pt' args.psp_encoder_ckpt = f'{project_path}/pretrained_models/psp_encoder.pt' args.style_img_path = f'{project_path}/test_imgs/style_imgs/' - args.add_weight_index = 6 - args.outdir = '/src/api/public/ai/style_transfer' + args.add_weight_index = 10 + args.outdir = '/src/server/public/ai/style_transfer' args.channel_multiplier = 2 args.latent = 512 args.n_mlp = 8 diff --git a/src/ai/anime/main.py b/src/ai/anime/main.py index 43b7a9d..0b15db5 100644 --- a/src/ai/anime/main.py +++ b/src/ai/anime/main.py @@ -17,7 +17,7 @@ args = parser.parse_args() project_path = "/home/alotaima/Projects/side/onlysudo/src/ai/anime" - args.outdir = '/src/api/public/ai/anime' + args.outdir = '/src/server/public/ai/anime' root_path = '/'.join(os.path.abspath(os.getcwd()).split('/')[:-2]) output_path = f"{root_path}{args.outdir}/{args.filename}" diff --git a/src/ai/pixel/main.py b/src/ai/pixel/main.py index 557beb1..273240e 100644 --- a/src/ai/pixel/main.py +++ b/src/ai/pixel/main.py @@ -19,7 +19,7 @@ args = parser.parse_args() project_path = "/home/alotaima/Projects/side/onlysudo/src/ai/pyxelate" - args.outdir = '/src/api/public/ai/pixel' + args.outdir = '/src/server/public/ai/pixel' # args.outdir = '/api/public/ai/pixel' root_path = '/'.join(os.path.abspath(os.getcwd()).split('/')[:-2]) diff --git a/src/api/index.js b/src/api/index.js deleted file mode 100644 index 7219152..0000000 --- a/src/api/index.js +++ /dev/null @@ -1,43 +0,0 @@ -const express = require("express"), - mongoose = require("mongoose"), - ejs = require("ejs"); - -const router = require("./routes/index"), - streamer_router = require("./routes/streamer"), - rank_router = require("./routes/rank"), - validate_router = require("./routes/validate"), - ai_router = require("./routes/ai"); - -require("dotenv").config({ path: "../../.env" }); - -const app = express(), - port = process.env.PORT || 4000; - -app.use(express.json()); -app.use(express.static(__dirname + "/public")); //Serves resources from public folder -app.set("view engine", "ejs"); - -main().catch((err) => console.log(err)); - -async function main() { - await mongoose - .connect(process.env.DATABASE_URL, { - useNewUrlParser: true, - useUnifiedTopology: true, - tlsCAFile: "../../ca-certificate.crt", - }) - .catch((err) => { - console.error(err.stack); - process.exit(1); - }); -} - -app.use("/streamer", streamer_router); -app.use("/rank", rank_router); -app.use("/validate", validate_router); -app.use("/ai", ai_router); -app.use("/", router); - -app.listen(port, () => { - console.log(`localhost:${port}`); -}); diff --git a/src/api/models/Rank.js b/src/api/models/Rank.js deleted file mode 100644 index b6e68ba..0000000 --- a/src/api/models/Rank.js +++ /dev/null @@ -1,19 +0,0 @@ -const mongoose = require("mongoose"); - -const rankSchema = new mongoose.Schema({ - name: { type: String, required: true }, - roleId: { type: String, required: true }, - channelId: { type: String, required: true }, - threshold: { type: Number, required: true }, -}); - -// streamerSchema.methods.stream = function stream() { -// const greeting = this.text -// ? "Meow name is " + this.text -// : "I don't have a name"; -// console.log(greeting); -// }; - -module.exports = { - Rank: mongoose.model("Ranks", rankSchema), -}; diff --git a/src/api/models/Streamer.js b/src/api/models/Streamer.js deleted file mode 100644 index eebc873..0000000 --- a/src/api/models/Streamer.js +++ /dev/null @@ -1,57 +0,0 @@ -const mongoose = require("mongoose"); - -const twitchInfo = { - twitchName: { type: String, required: true }, - twitchId: { type: String, required: true }, - profileImg: { type: String, default: "" }, -}; - -const twitchStats = { - streams: { type: Number, default: 0 }, - hosts: { type: Number, default: 0 }, - raids: { type: Number, default: 0 }, - chats: { type: Number, default: 0 }, - views: { type: Number, required: false }, - follows: { type: Number, required: false }, -}; - -const rankInfo = { - rankName: { type: String, default: "" }, - points: { type: Number, default: 0 }, - activityPoints: { type: Number, default: 0 }, - streamsBeforeDemotion: { type: Number, default: 0 }, -}; - -const invitationInfo = { - invitedUsers: { - type: [Number], - default: [], - }, - invites: { - type: Number, - default: 0, - }, - eventIds: { - type: [String], - default: [], - }, -}; - -const streamerSchema = new mongoose.Schema({ - discordId: { type: String, required: true }, - ...twitchInfo, - ...twitchStats, - ...rankInfo, - ...invitationInfo, -}); - -// streamerSchema.methods.stream = function stream() { -// const greeting = this.text -// ? "Meow name is " + this.text -// : "I don't have a name"; -// console.log(greeting); -// }; - -module.exports = { - Streamer: mongoose.model("Streamers", streamerSchema), -}; diff --git a/src/api/routes/ai.js b/src/api/routes/ai.js deleted file mode 100644 index 3791795..0000000 --- a/src/api/routes/ai.js +++ /dev/null @@ -1,107 +0,0 @@ -const express = require("express"), - router = express.Router(); - -const python_path = "/home/alotaima/miniconda3/bin/python"; - -function getProgramPath(project) { - const rootFolder = __dirname.split("/"); - rootFolder.splice(-2, 2, `ai/${project}/main.py`); - return rootFolder.join("/"); -} - -function launchProcess(res, args) { - const spawn = require("child_process").spawn, - process = spawn(python_path, args); - - let output = ""; - - process.stdout.on("data", function (data) { - output += data.toString(); - }); - - process.stderr.on("data", (data) => { - console.error(`stderr: ${data}`); - }); - process.on("close", (code) => { - console.log(output); - res.send(JSON.stringify(output)); - }); -} - -router.post("/style_transfer", (req, res) => { - const args = [ - getProgramPath("BlendGAN"), - `--url`, - `${req.body.url}`, - `--style_selected`, - `${req.body.style_selected}`, - `--filename`, - `${req.body.filename}`, - ]; - - launchProcess(res, args); -}); - -router.post("/pixel", (req, res) => { - const args = [ - getProgramPath("pixel"), - `--url`, - `${req.body.url}`, - `--palette`, - `${req.body.palette}`, - `--filename`, - `${req.body.filename}`, - ]; - - launchProcess(res, args); -}); - -router.post("/arcane", (req, res) => { - const args = [ - getProgramPath("ArcaneGAN"), - `--url`, - `${req.body.url}`, - `--filename`, - `${req.body.filename}`, - ]; - - launchProcess(res, args); -}); - -router.post("/chat", (req, res) => { - const args = [getProgramPath("chat"), `--message`, `${req.body.message}`]; - - launchProcess(res, args); -}); - -router.post("/wolf", (req, res) => { - const args = [getProgramPath("wolf"), `--message`, `${req.body.message}`]; - - launchProcess(res, args); -}); - -router.post("/ar", (req, res) => { - const args = [getProgramPath("ar"), `--message`, `${req.body.message}`]; - - launchProcess(res, args); -}); - -router.post("/en", (req, res) => { - const args = [getProgramPath("en"), `--message`, `${req.body.message}`]; - - launchProcess(res, args); -}); - -router.post("/anime", (req, res) => { - const args = [ - getProgramPath("anime"), - `--url`, - `${req.body.url}`, - `--filename`, - `${req.body.filename}`, - ]; - - launchProcess(res, args); -}); - -module.exports = router; diff --git a/src/api/routes/index.js b/src/api/routes/index.js deleted file mode 100644 index 0f1ea2a..0000000 --- a/src/api/routes/index.js +++ /dev/null @@ -1,15 +0,0 @@ -const express = require("express"), - router = express.Router(); - -router.get("/style", (req, res) => { - res.render("style"); -}); -router.post("/", (req, res) => { - console.log(JSON.stringify("Hello World!")); - res.send(JSON.stringify("Hello World!")); -}); -router.get("/", (req, res) => { - res.send(JSON.stringify("Hello World!")); -}); - -module.exports = router; diff --git a/src/api/routes/rank.js b/src/api/routes/rank.js deleted file mode 100644 index 2a7289f..0000000 --- a/src/api/routes/rank.js +++ /dev/null @@ -1,45 +0,0 @@ -const express = require("express"), - router = express.Router(); - -const { Rank } = require("../models/Rank"); - -router.post("/", async (req, res) => { - const rank = new Rank({ text: req.body.text }); - await rank.save(); - - // rank.stream() - - res.send({ rank }); -}); - -router.put("/:rankId", async (req, res) => { - const rankId = req.params.rankId; - const text = req.body.text; - - const rank = await Rank.findByIdAndUpdate({ _id: rankId }, { text }); - - res.json({ rank }); -}); - -router.delete("/:rankId", async (req, res) => { - const rankId = req.params.rankId; - - const rank = await Rank.deleteOne({ _id: rankId }); - - res.json({ rank }); -}); - -router.get("/:rankId", async (req, res) => { - const rankId = req.params.rankId; - const rank = await Rank.find({ _id: rankId }); - - res.json({ rank }); -}); - -router.get("/", async (req, res) => { - const ranks = await Rank.find(); - - res.json({ ranks }); -}); - -module.exports = router; diff --git a/src/api/routes/streamer.js b/src/api/routes/streamer.js deleted file mode 100644 index 947268f..0000000 --- a/src/api/routes/streamer.js +++ /dev/null @@ -1,45 +0,0 @@ -const express = require("express"), - router = express.Router(); - -const { Streamer } = require("../models/Streamer"); - -router.post("/", async (req, res) => { - const streamer = new Streamer({ text: req.body.text }); - await streamer.save(); - streamer.stream(); - - res.send({ streamer }); -}); - -router.put("/:streamerId", async (req, res) => { - const streamerId = req.params.streamerId; - const text = req.body.text; - - const streamer = await Streamer.findByIdAndUpdate( - { _id: streamerId }, - { text } - ); - - res.json({ streamer }); -}); - -router.delete("/:streamerId", async (req, res) => { - const streamerId = req.params.streamerId; - - const streamer = await Streamer.deleteOne({ _id: streamerId }); - - res.json({ streamer }); -}); - -router.get("/:streamerId", async (req, res) => { - const streamerId = req.params.streamerId; - const streamer = await Streamer.find({ _id: streamerId }); - res.json({ streamer }); -}); - -router.get("/", async (req, res) => { - const streamers = await Streamer.find(); - res.json({ streamers }); -}); - -module.exports = router; diff --git a/src/api/routes/validate.js b/src/api/routes/validate.js deleted file mode 100644 index be095dd..0000000 --- a/src/api/routes/validate.js +++ /dev/null @@ -1,95 +0,0 @@ -const express = require("express"), - router = express.Router(); - -require("dotenv").config({ path: "../../../.env" }); - -router.get("/discord", async ({ query }, response) => { - const { code } = query; - - if (code) { - try { - const oauthResult = await fetch( - "https://discord.com/api/oauth2/token", - { - method: "POST", - body: new URLSearchParams({ - client_id: process.env.DISCORD_CLIENT_ID, - client_secret: process.env.DISCORD_CLIENT_SECRET, - code, - grant_type: "authorization_code", - redirect_uri: `http://localhost:${port}/validate/discord`, - scope: "identify", - }), - headers: { - "Content-Type": "application/x-www-form-urlencoded", - }, - } - ); - - const oauthData = await oauthResult.json(); - console.log(oauthData); - const userResult = await fetch( - "https://discord.com/api/users/@me", - { - headers: { - authorization: `${oauthData.token_type} ${oauthData.access_token}`, - }, - } - ); - - console.log(await userResult.json()); - } catch (error) { - // NOTE: An unauthorized token will not throw an error; - // it will return a 401 Unauthorized response in the try block above - console.error(error); - } - } - - return response.sendFile("index.html", { root: "./views" }); -}); - -router.get("/twitch", async ({ query }, response) => { - const { code } = query; - - if (code) { - try { - const oauthResult = await fetch( - "https://discord.com/api/oauth2/token", - { - method: "POST", - body: new URLSearchParams({ - client_id: process.env.DISCORD_CLIENT_ID, - client_secret: process.env.DISCORD_CLIENT_SECRET, - code, - grant_type: "authorization_code", - redirect_uri: `http://localhost:${port}`, - scope: "identify", - }), - headers: { - "Content-Type": "application/x-www-form-urlencoded", - }, - } - ); - - const oauthData = await oauthResult.json(); - - const userResult = await fetch( - "https://discord.com/api/users/@me", - { - headers: { - authorization: `${oauthData.token_type} ${oauthData.access_token}`, - }, - } - ); - - console.log(await userResult.json()); - } catch (error) { - // NOTE: An unauthorized token will not throw an error; - // it will return a 401 Unauthorized response in the try block above - console.error(error); - } - } - - return response.sendFile("index.html", { root: "./views" }); -}); -module.exports = router; diff --git a/src/api/server.js b/src/api/server.js new file mode 100644 index 0000000..55fbff4 --- /dev/null +++ b/src/api/server.js @@ -0,0 +1,29 @@ +require('dotenv').config({path:'../../.env'}); + +const axios = require('axios'); + +const URL = `http://localhost:${process.env.PORT}`; + +module.exports = { + postRequest(client, channel, url, args) { + axios + .post(`${URL}${url}`, args) + .then((res) => { + client.say(channel, res.data); + }) + .catch((error) => { + console.error(error); + }); + }, + postRequestMore(client, channel, url, args, msg) { + axios + .post(`${URL}${url}`, args) + .then((res) => { + client.say(channel, msg[1]); + }) + .catch((error) => { + console.error(error); + }); + client.say(channel, msg[0]); + } +} \ No newline at end of file diff --git a/src/api/twitch.js b/src/api/twitch.js new file mode 100644 index 0000000..db86469 --- /dev/null +++ b/src/api/twitch.js @@ -0,0 +1,43 @@ +require('dotenv').config({path:'../../.env'}); + +const axios = require('axios'); + +const URL = `https://api.twitch.tv/helix`; + +function getRequestTwitch(url, cb) { + axios.get(`${URL}${url}`, { + headers: { + "Client-ID": process.env.TWITCH_CLIENT_ID, + "Authorization": `Bearer ${process.env.TWITCH_ACCESS_TOKEN}` + } + }) + .then(async res => { + cb(await res.data) + }).catch(err => console.log(err)) +} + +module.exports = { + getFollowers(twitchId, cb) { + getRequestTwitch(`/users?from_id=${twitchId}&first=1`, (data) => { + if(cb) cb(data.total); + }) + }, + getUser(twitchName, cb) { + getRequestTwitch(`/users?login=${twitchName}`, (data) => { + if(cb) { + if (data.data.length === 0) { + return cb(null); + } + cb(data.data[0]) + } + }) + }, + // clips - https://dev.twitch.tv/docs/api/reference#get-clips + // game_id, game_name, type (live), title, viewer_count, start_at, is_mature + getStreams(twitchId, cb) { + console.log(twitchId) + getRequestTwitch(`/streams?user_id=${twitchId}&first=1`, (data) => { + if(cb) cb(data.data[0]); + }) + } +} \ No newline at end of file diff --git a/src/discord_bot/commands/ar.js b/src/discord/commands/ar.js similarity index 94% rename from src/discord_bot/commands/ar.js rename to src/discord/commands/ar.js index c4d5d1a..66c39bb 100644 --- a/src/discord_bot/commands/ar.js +++ b/src/discord/commands/ar.js @@ -1,6 +1,6 @@ const { SlashCommandBuilder } = require("@discordjs/builders"); -const { postRequest } = require("../utils/request"); +const { postRequest } = require("../../api/server"); module.exports = { data: new SlashCommandBuilder() diff --git a/src/discord_bot/commands/arcane.js b/src/discord/commands/arcane.js similarity index 95% rename from src/discord_bot/commands/arcane.js rename to src/discord/commands/arcane.js index c7260c8..f832deb 100644 --- a/src/discord_bot/commands/arcane.js +++ b/src/discord/commands/arcane.js @@ -1,7 +1,7 @@ const { SlashCommandBuilder } = require("@discordjs/builders"); -const { makeid } = require("../utils/utils"); -const { postRequestMore } = require("../utils/request"); +const { makeid } = require("../utils"); +const { postRequestMore } = require("../../api/server"); module.exports = { data: new SlashCommandBuilder() diff --git a/src/discord_bot/commands/avatar.js b/src/discord/commands/avatar.js similarity index 100% rename from src/discord_bot/commands/avatar.js rename to src/discord/commands/avatar.js diff --git a/src/discord_bot/commands/en.js b/src/discord/commands/en.js similarity index 94% rename from src/discord_bot/commands/en.js rename to src/discord/commands/en.js index 6614709..1ea1085 100644 --- a/src/discord_bot/commands/en.js +++ b/src/discord/commands/en.js @@ -1,6 +1,6 @@ const { SlashCommandBuilder } = require("@discordjs/builders"); -const { postRequest } = require("../utils/request"); +const { postRequest } = require("../../api/server"); module.exports = { data: new SlashCommandBuilder() diff --git a/src/discord_bot/commands/ping.js b/src/discord/commands/ping.js similarity index 100% rename from src/discord_bot/commands/ping.js rename to src/discord/commands/ping.js diff --git a/src/discord_bot/commands/wolf.js b/src/discord/commands/wolf.js similarity index 94% rename from src/discord_bot/commands/wolf.js rename to src/discord/commands/wolf.js index d3b38b5..0ed1749 100644 --- a/src/discord_bot/commands/wolf.js +++ b/src/discord/commands/wolf.js @@ -1,6 +1,6 @@ const { SlashCommandBuilder } = require("@discordjs/builders"); -const { postRequest } = require("../utils/request"); +const { postRequest } = require("../../api/server"); module.exports = { data: new SlashCommandBuilder() diff --git a/src/discord_bot/deploy-commands.js b/src/discord/deploy-commands.js similarity index 100% rename from src/discord_bot/deploy-commands.js rename to src/discord/deploy-commands.js diff --git a/src/discord_bot/events/interactionCraete.js b/src/discord/events/interactionCraete.js similarity index 100% rename from src/discord_bot/events/interactionCraete.js rename to src/discord/events/interactionCraete.js diff --git a/src/discord_bot/events/messageCreate.js b/src/discord/events/messageCreate.js similarity index 100% rename from src/discord_bot/events/messageCreate.js rename to src/discord/events/messageCreate.js diff --git a/src/discord_bot/events/ready.js b/src/discord/events/ready.js similarity index 100% rename from src/discord_bot/events/ready.js rename to src/discord/events/ready.js diff --git a/src/discord_bot/templates/command.js b/src/discord/templates/command.js similarity index 100% rename from src/discord_bot/templates/command.js rename to src/discord/templates/command.js diff --git a/src/discord_bot/utils/utils.js b/src/discord/utils.js similarity index 100% rename from src/discord_bot/utils/utils.js rename to src/discord/utils.js diff --git a/src/discord_bot/commands/register.js b/src/discord_bot/commands/register.js deleted file mode 100644 index 5785a69..0000000 --- a/src/discord_bot/commands/register.js +++ /dev/null @@ -1,18 +0,0 @@ -const { SlashCommandBuilder } = require("@discordjs/builders"); - -module.exports = { - data: new SlashCommandBuilder() - .setName("register") - .setDescription("dd") - .addUserOption((option) => { - return option - .setName("username") - .setRequired(true) - .setDescription("The username of the user to register"); - }), - async execute(client, interaction) { - const role = interaction.options.getRole("streamer"); - const member = interaction.options.getMember("target"); - member.roles.add(role); - }, -}; diff --git a/src/discord_bot/commands/reset.js b/src/discord_bot/commands/reset.js deleted file mode 100644 index afc46bb..0000000 --- a/src/discord_bot/commands/reset.js +++ /dev/null @@ -1,20 +0,0 @@ -require("dotenv").config({ path: `../../.env` }); -const { SlashCommandBuilder } = require("@discordjs/builders"); - -// Turn bot off (destroy), then turn it back on -function resetBot(channel) { - // send channel a message that you're resetting bot [optional] - channel - .send("Resetting...") - .then((msg) => client.destroy()) - .then(() => client.login(process.env.DISCORD_BOT_TOKEN)); -} - -module.exports = { - data: new SlashCommandBuilder() - .setName("reset") - .setDescription("Replies with Pong!"), - async execute(client, interaction) { - resetBot(interaction.channel); - }, -}; diff --git a/src/discord_bot/commands/server.js b/src/discord_bot/commands/server.js deleted file mode 100644 index 4194bad..0000000 --- a/src/discord_bot/commands/server.js +++ /dev/null @@ -1,13 +0,0 @@ -const { SlashCommandBuilder } = require("@discordjs/builders"); - -module.exports = { - data: new SlashCommandBuilder() - .setName("server") - .setDescription("Display info about this server."), - async execute(client, interaction) { - return interaction.reply( - `Server name: ` + - `${interaction.guild.name}\nTotal members: ${interaction.guild.memberCount}` - ); - }, -}; diff --git a/src/discord_bot/commands/user.js b/src/discord_bot/commands/user.js deleted file mode 100644 index 15a07b4..0000000 --- a/src/discord_bot/commands/user.js +++ /dev/null @@ -1,14 +0,0 @@ -const { SlashCommandBuilder } = require("@discordjs/builders"); - -module.exports = { - data: new SlashCommandBuilder() - .setName("user") - .setDescription("Display info about yourself."), - async execute(client, interaction) { - return interaction.reply( - `Your username: ` + - `${interaction.user.username}\n` + - `Your ID: ${interaction.user.id}` - ); - }, -}; diff --git a/src/discord_bot/index.js b/src/discord_bot/index.js deleted file mode 100644 index e85c406..0000000 --- a/src/discord_bot/index.js +++ /dev/null @@ -1,43 +0,0 @@ -require("dotenv").config({ path: "../../.env" }); - -const fs = require("fs"), - { Client, Collection, Intents } = require("discord.js"); - -// client -const client = new Client({ - intents: [Intents.FLAGS.GUILDS, Intents.FLAGS.GUILD_MESSAGES], -}); - -// commands -client.commands = new Collection(); - -const commandFiles = fs - .readdirSync("./commands") - .filter((file) => file.endsWith(".js")); -// const permissions = require('./permissions'); - -for (const file of commandFiles) { - const command = require(`./commands/${file}`); - // await command.permissions.add({ permissions }); - client.commands.set(command.data.name, command); -} - -// events -const eventFiles = fs - .readdirSync("./events") - .filter((file) => file.endsWith(".js")); - -for (const file of eventFiles) { - const event = require(`./events/${file}`); - if (event.once) { - client.once(event.name, (...args) => { - event.execute(client, ...args); - }); - } else { - client.on(event.name, (...args) => { - event.execute(client, ...args); - }); - } -} - -client.login(process.env.DISCORD_TOKEN); diff --git a/src/discord_bot/permissions.js b/src/discord_bot/permissions.js deleted file mode 100644 index 00207ce..0000000 --- a/src/discord_bot/permissions.js +++ /dev/null @@ -1,7 +0,0 @@ -const permissions = [ - { - id: "464464090157416448", - type: "ROLE", - permission: false, - }, -]; diff --git a/src/discord_bot/utils/request.js b/src/discord_bot/utils/request.js deleted file mode 100644 index d092da2..0000000 --- a/src/discord_bot/utils/request.js +++ /dev/null @@ -1,37 +0,0 @@ -require("dotenv").config({ path: "../../.env" }); - -const fetch = require("node-fetch"); - -async function postRequest(client, interaction, url, args, calllbacks) { - await fetch(`http://localhost:${process.env.PORT}${url}`, { - method: "POST", - body: JSON.stringify(args), - headers: { "Content-Type": "application/json" }, - }) - .then(async (res) => { - calllbacks(await res.json()); - }) - .catch((error) => { - calllbacks(error); - }); -} - -async function postRequestMore(client, interaction, url, args, msg, calllbacks) { - await fetch(`http://localhost:${process.env.PORT}${url}`, { - method: "POST", - body: JSON.stringify(args), - headers: { "Content-Type": "application/json" }, - }) - .then(async (res) => { - console.log(await res.json()); - calllbacks(msg[1]); - }) - .catch((error) => { - calllbacks(error); - }); - calllbacks(msg[0]); -} -module.exports = { - postRequest, - postRequestMore, -}; diff --git a/src/index.js b/src/index.js new file mode 100644 index 0000000..b9c9d5b --- /dev/null +++ b/src/index.js @@ -0,0 +1,64 @@ +require('dotenv').config({path:'../.env'}); + +process.env.BASE_URL = 'https://9d8d-96-44-8-65.ngrok.io' + +const express = require('express'), + mongoose = require('mongoose'), + fs = require('fs'), + { EventEmitter } = require("events"); + +const {TwitchBot} = require('./TwitchBot'), + {DiscordBot} = require('./DiscordBot'); + +const app = express(), +port = process.env.PORT || 4000; + +app.use(express.json()); +app.use(express.raw({ type: 'application/json' })); // Need raw message body for signature verification +app.use(express.static(__dirname + '/server/public')); //Serves resources from public folder +app.set('views', __dirname+'/server/views/'); // fix issue with subdirectory +app.set('view engine', 'ejs'); + +main().catch(err => console.log(err)); + +async function main() { + await mongoose.connect(process.env.DATABASE_URL, { + useNewUrlParser: true, + useUnifiedTopology: true, + tlsCAFile: "../ca-certificate.crt" + }).catch(err => { + console.error(err.stack) + process.exit(1) + }); +} + +// routes +const routesFiles = fs.readdirSync('./server/routes').filter(file => file.endsWith('.js')); + +const emitter = new EventEmitter(); + +for (const file of routesFiles) { + const router = require(`./server/routes/${file}`); + app.use(router.path, new router.Router(emitter).router); +} + +const delay = ms => new Promise(res => setTimeout(res, ms)); + +app.listen(port, async () => { + console.log(`localhost:${port}`) + const channels = ['sudomaze'] + const twitchBot = new TwitchBot(channels), + discordBot = new DiscordBot(); + twitchBot.start(); + discordBot.start(); + console.log('starting...') + while(twitchBot.client.readyState() !== "OPEN" || !discordBot.client.isReady()) { + await delay(1000); + if(twitchBot.client.readyState() === "CLOSED") { + twitchBot.disconnect(); + twitchBot.start(); + } + } + console.log('ready!') + +}); \ No newline at end of file diff --git a/src/api/public/.gitignore b/src/server/public/.gitignore similarity index 100% rename from src/api/public/.gitignore rename to src/server/public/.gitignore diff --git a/src/server/routes/ai.js b/src/server/routes/ai.js new file mode 100644 index 0000000..9ef30c4 --- /dev/null +++ b/src/server/routes/ai.js @@ -0,0 +1,111 @@ +const express = require("express"); + +const python_path = "/home/alotaima/miniconda3/bin/python"; + +function getProgramPath(project) { + const rootFolder = __dirname.split("/"); + rootFolder.splice(-2, 2, `ai/${project}/main.py`); + return rootFolder.join("/"); +} + +function launchProcess(res, args) { + const spawn = require("child_process").spawn, + process = spawn(python_path, args); + + let output = ""; + + process.stdout.on("data", function (data) { + output += data.toString(); + }); + + process.stderr.on("data", (data) => { + console.error(`stderr: ${data}`); + }); + process.on("close", (code) => { + console.log(output); + res.send(JSON.stringify(output)); + }); +} + +class Router { + constructor(emitter) { + this.router = express.Router(); + this.emitter = emitter + this.router.post("/style_transfer", (req, res) => { + const args = [ + getProgramPath("BlendGAN"), + `--url`, + `${req.body.url}`, + `--style_selected`, + `${req.body.style_selected}`, + `--filename`, + `${req.body.filename}`, + ]; + + launchProcess(res, args); + }); + + this.router.post("/pixel", (req, res) => { + const args = [ + getProgramPath("pixel"), + `--url`, + `${req.body.url}`, + `--palette`, + `${req.body.palette}`, + `--filename`, + `${req.body.filename}`, + ]; + + launchProcess(res, args); + }); + + this.router.post("/arcane", (req, res) => { + const args = [ + getProgramPath("ArcaneGAN"), + `--url`, + `${req.body.url}`, + `--filename`, + `${req.body.filename}`, + ]; + + launchProcess(res, args); + }); + + this.router.post("/chat", (req, res) => { + const args = [getProgramPath("chat"), `--message`, `${req.body.message}`]; + + launchProcess(res, args); + }); + + this.router.post("/wolf", (req, res) => { + const args = [getProgramPath("wolf"), `--message`, `${req.body.message}`]; + + launchProcess(res, args); + }); + + this.router.post("/ar", (req, res) => { + const args = [getProgramPath("ar"), `--message`, `${req.body.message}`]; + + launchProcess(res, args); + }); + + this.router.post("/en", (req, res) => { + const args = [getProgramPath("en"), `--message`, `${req.body.message}`]; + + launchProcess(res, args); + }); + + this.router.post("/anime", (req, res) => { + const args = [ + getProgramPath("anime"), + `--url`, + `${req.body.url}`, + `--filename`, + `${req.body.filename}`, + ]; + + launchProcess(res, args); + }); + } +} +module.exports = { path: "/ai", Router }; diff --git a/src/server/routes/index.js b/src/server/routes/index.js new file mode 100644 index 0000000..48d813c --- /dev/null +++ b/src/server/routes/index.js @@ -0,0 +1,16 @@ +const express = require('express'); + +class Router { + constructor(emitter) { + this.router = express.Router(); + this.emitter = emitter + this.router.get('/style', (req, res) => { + res.render('style'); + }) + this.router.get('/', (req, res) => { + res.send('Hello World!') + }) + } +} + +module.exports = { path: "/", Router }; diff --git a/src/api/views/index.html b/src/server/views/index.html similarity index 100% rename from src/api/views/index.html rename to src/server/views/index.html diff --git a/src/api/views/style.ejs b/src/server/views/style.ejs similarity index 100% rename from src/api/views/style.ejs rename to src/server/views/style.ejs diff --git a/src/twitch_bot/commands/anime.js b/src/twitch/commands/anime.js similarity index 90% rename from src/twitch_bot/commands/anime.js rename to src/twitch/commands/anime.js index 19b9759..9aa5d6f 100644 --- a/src/twitch_bot/commands/anime.js +++ b/src/twitch/commands/anime.js @@ -1,7 +1,7 @@ require("dotenv").config({ path: "../../../.env" }); -const { makeid } = require("../utils/utils"); -const { postRequestMore } = require("../utils/request"); +const { makeid } = require("../utils"); +const { postRequestMore } = require("../../api/server"); module.exports = { name: "anime", diff --git a/src/twitch_bot/commands/ar.js b/src/twitch/commands/ar.js similarity index 86% rename from src/twitch_bot/commands/ar.js rename to src/twitch/commands/ar.js index da49de9..429366a 100644 --- a/src/twitch_bot/commands/ar.js +++ b/src/twitch/commands/ar.js @@ -1,4 +1,4 @@ -const { postRequest } = require("../utils/request"); +const { postRequest } = require("../../api/server"); module.exports = { name: "ar", diff --git a/src/twitch_bot/commands/arcane.js b/src/twitch/commands/arcane.js similarity index 90% rename from src/twitch_bot/commands/arcane.js rename to src/twitch/commands/arcane.js index 83df13f..1039da8 100644 --- a/src/twitch_bot/commands/arcane.js +++ b/src/twitch/commands/arcane.js @@ -1,7 +1,7 @@ require("dotenv").config({ path: "../../../.env" }); -const { makeid } = require("../utils/utils"); -const { postRequestMore } = require("../utils/request"); +const { makeid } = require("../utils"); +const { postRequestMore } = require("../../api/server"); module.exports = { name: "arcane", diff --git a/src/twitch_bot/commands/art.js b/src/twitch/commands/art.js similarity index 91% rename from src/twitch_bot/commands/art.js rename to src/twitch/commands/art.js index 123886a..4050615 100644 --- a/src/twitch_bot/commands/art.js +++ b/src/twitch/commands/art.js @@ -1,7 +1,7 @@ require("dotenv").config({ path: "../../../.env" }); -const { makeid, getRandomInt } = require("../utils/utils"); -const { postRequestMore } = require("../utils/request"); +const { makeid, getRandomInt } = require("../utils"); +const { postRequestMore } = require("../../api/server"); module.exports = { name: "art", diff --git a/src/twitch_bot/commands/bye.js b/src/twitch/commands/bye.js similarity index 100% rename from src/twitch_bot/commands/bye.js rename to src/twitch/commands/bye.js diff --git a/src/twitch_bot/commands/chat.js b/src/twitch/commands/chat.js similarity index 86% rename from src/twitch_bot/commands/chat.js rename to src/twitch/commands/chat.js index 9d2bd19..80a5581 100644 --- a/src/twitch_bot/commands/chat.js +++ b/src/twitch/commands/chat.js @@ -1,4 +1,4 @@ -const { postRequest } = require("../utils/request"); +const { postRequest } = require("../../api/server"); module.exports = { name: "chat", diff --git a/src/twitch_bot/commands/en.js b/src/twitch/commands/en.js similarity index 86% rename from src/twitch_bot/commands/en.js rename to src/twitch/commands/en.js index dc84f2f..cac2ce3 100644 --- a/src/twitch_bot/commands/en.js +++ b/src/twitch/commands/en.js @@ -1,4 +1,4 @@ -const { postRequest } = require("../utils/request"); +const { postRequest } = require("../../api/server"); module.exports = { name: "en", diff --git a/src/twitch/commands/hi.js b/src/twitch/commands/hi.js new file mode 100644 index 0000000..ec7460e --- /dev/null +++ b/src/twitch/commands/hi.js @@ -0,0 +1,11 @@ +module.exports = { + name: "hi", + description: "Ping!", + async execute(client, channel, context, msg, args) { + client.say( + channel, + `Hi @${channel.replace('#','')}, ` + + `@${context.username} brought me here! I'm a bot and I am alive!!` + ).catch(err => console.log(err)); + }, +}; diff --git a/src/twitch_bot/commands/hi.js b/src/twitch/commands/link.js similarity index 52% rename from src/twitch_bot/commands/hi.js rename to src/twitch/commands/link.js index b024626..004ca09 100644 --- a/src/twitch_bot/commands/hi.js +++ b/src/twitch/commands/link.js @@ -1,11 +1,12 @@ +require('dotenv').config({path:'../../../env'}); + module.exports = { - name: "hi", + name: "link", description: "Ping!", async execute(client, channel, context, msg, args) { client.say( channel, - `Hi @${channel.replace("#", "")}, ` + - `@${context.username} brought me here! I'm a bot and I am alive!!` + process.env.BASE_URL ); }, }; diff --git a/src/twitch_bot/commands/ping.js b/src/twitch/commands/ping.js similarity index 55% rename from src/twitch_bot/commands/ping.js rename to src/twitch/commands/ping.js index da8c07d..0f24e4b 100644 --- a/src/twitch_bot/commands/ping.js +++ b/src/twitch/commands/ping.js @@ -2,6 +2,9 @@ module.exports = { name: "ping", description: "Ping!", async execute(client, channel, context, msg, args) { - client.say(channel, "Pong."); + client.say( + channel, + "Pong." + ).catch(err => console.log(err)); }, }; diff --git a/src/twitch_bot/commands/pixel.js b/src/twitch/commands/pixel.js similarity index 90% rename from src/twitch_bot/commands/pixel.js rename to src/twitch/commands/pixel.js index aeccdd9..1af4dbe 100644 --- a/src/twitch_bot/commands/pixel.js +++ b/src/twitch/commands/pixel.js @@ -1,7 +1,7 @@ require("dotenv").config({ path: "../../../.env" }); -const { makeid, getRandomInt } = require("../utils/utils"); -const { postRequestMore } = require("../utils/request"); +const { makeid } = require("../utils"); +const { postRequestMore } = require("../../api/server"); module.exports = { name: "pixel", diff --git a/src/twitch_bot/commands/wolf.js b/src/twitch/commands/wolf.js similarity index 86% rename from src/twitch_bot/commands/wolf.js rename to src/twitch/commands/wolf.js index 048df0c..8b740e7 100644 --- a/src/twitch_bot/commands/wolf.js +++ b/src/twitch/commands/wolf.js @@ -1,4 +1,4 @@ -const { postRequest } = require("../utils/request"); +const { postRequest } = require("../../api/server"); module.exports = { name: "wolf", diff --git a/src/twitch_bot/events/connected.js b/src/twitch/events/connected.js similarity index 100% rename from src/twitch_bot/events/connected.js rename to src/twitch/events/connected.js diff --git a/src/twitch_bot/events/message.js b/src/twitch/events/message.js similarity index 100% rename from src/twitch_bot/events/message.js rename to src/twitch/events/message.js diff --git a/src/twitch/utils.js b/src/twitch/utils.js new file mode 100644 index 0000000..2c4a0f2 --- /dev/null +++ b/src/twitch/utils.js @@ -0,0 +1,19 @@ +function makeid(length) { + var result = ''; + var characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'; + var charactersLength = characters.length; + for ( var i = 0; i < length; i++ ) { + result += characters.charAt(Math.floor(Math.random() * + charactersLength)); + } + return result; +} + +function getRandomInt(max) { + return Math.floor(Math.random() * max); +} + +module.exports = { + makeid, + getRandomInt, +} \ No newline at end of file diff --git a/src/twitch_bot/index.js b/src/twitch_bot/index.js deleted file mode 100644 index 0698f84..0000000 --- a/src/twitch_bot/index.js +++ /dev/null @@ -1,47 +0,0 @@ -require("dotenv").config({ path: "../../.env" }); - -const fs = require("fs"), - { Client } = require("tmi.js"), - { Collection } = require("discord.js"); - -// client -const client = new Client({ - options: { debug: true, messagesLogLevel: "info" }, - connection: { - reconnect: true, - secure: true, - }, - identity: { - username: `${process.env.TWITCH_BOT_USERNAME}`, - password: `oauth:${process.env.TWITCH_ACCESS_TOKEN}`, - }, - channels: [`${process.env.TWITCH_CHANNEL}` ], -}); - -// commands -client.commands = new Collection(); - -const commandFiles = fs - .readdirSync("./commands") - .filter((file) => file.endsWith(".js")); - -for (const file of commandFiles) { - const command = require(`./commands/${file}`); - client.commands.set(command.name, command); -} - -// events -const eventFiles = fs - .readdirSync("./events") - .filter((file) => file.endsWith(".js")); - -for (const file of eventFiles) { - const event = require(`./events/${file}`); - if (event.once) { - client.once(event.name, (...args) => event.execute(client, ...args)); - } else { - client.on(event.name, (...args) => event.execute(client, ...args)); - } -} - -client.connect().catch(console.error); diff --git a/src/twitch_bot/utils/request.js b/src/twitch_bot/utils/request.js deleted file mode 100644 index d61fee6..0000000 --- a/src/twitch_bot/utils/request.js +++ /dev/null @@ -1,30 +0,0 @@ -require("dotenv").config({ path: "../../.env" }); - -const axios = require("axios"); - -function postRequest(client, channel, url, args) { - axios - .post(`http://localhost:${process.env.PORT}${url}`, args) - .then((res) => { - client.say(channel, res.data); - }) - .catch((error) => { - console.error(error); - }); -} - -function postRequestMore(client, channel, url, args, msg) { - axios - .post(`http://localhost:${process.env.PORT}${url}`, args) - .then((res) => { - client.say(channel, msg[1]); - }) - .catch((error) => { - console.error(error); - }); - client.say(channel, msg[0]); -} -module.exports = { - postRequest, - postRequestMore, -}; diff --git a/src/twitch_bot/utils/utils.js b/src/twitch_bot/utils/utils.js deleted file mode 100644 index 8b59086..0000000 --- a/src/twitch_bot/utils/utils.js +++ /dev/null @@ -1,21 +0,0 @@ -function makeid(length) { - var result = ""; - var characters = - "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; - var charactersLength = characters.length; - for (var i = 0; i < length; i++) { - result += characters.charAt( - Math.floor(Math.random() * charactersLength) - ); - } - return result; -} - -function getRandomInt(max) { - return Math.floor(Math.random() * max); -} - -module.exports = { - makeid, - getRandomInt, -};