Add initial Azure Functions support, clean up gitignore
This commit is contained in:
parent
dd7bd6b4cc
commit
6bf0537c29
11
.env.example
11
.env.example
|
@ -43,5 +43,12 @@ TMP_DOMAIN=
|
||||||
# Port for serving metrics. Metrics served are compatible with Prometheus.
|
# Port for serving metrics. Metrics served are compatible with Prometheus.
|
||||||
METRICS=
|
METRICS=
|
||||||
|
|
||||||
# Set this to true if you want to use the external image API script, located in api/index.js
|
# The image API type to be used
|
||||||
API=false
|
# Set this to `none` to process all images locally
|
||||||
|
# Set this to `ws` if you want to use the external image API script, located in api/index.js
|
||||||
|
# Set this to `azure` to use the Azure Functions API
|
||||||
|
API_TYPE=none
|
||||||
|
# If API_TYPE is `azure`, set this to your Azure webhook URL
|
||||||
|
AZURE_URL=
|
||||||
|
# If API_TYPE is `azure`, set an optional password for webhook responses
|
||||||
|
AZURE_PASS=
|
|
@ -1,42 +1,130 @@
|
||||||
cache/
|
# Logs
|
||||||
build/
|
|
||||||
data/
|
|
||||||
appold.js
|
|
||||||
migrate.js
|
|
||||||
config.json
|
|
||||||
.env
|
|
||||||
logs
|
logs
|
||||||
*.log
|
*.log
|
||||||
npm-debug.log*
|
npm-debug.log*
|
||||||
yarn-debug.log*
|
yarn-debug.log*
|
||||||
yarn-error.log*
|
yarn-error.log*
|
||||||
|
lerna-debug.log*
|
||||||
|
.pnpm-debug.log*
|
||||||
|
|
||||||
|
# Diagnostic reports (https://nodejs.org/api/report.html)
|
||||||
|
report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json
|
||||||
|
|
||||||
|
# Runtime data
|
||||||
pids
|
pids
|
||||||
*.pid
|
*.pid
|
||||||
*.seed
|
*.seed
|
||||||
*.pid.lock
|
*.pid.lock
|
||||||
lib-cov
|
|
||||||
coverage
|
# node-waf configuration
|
||||||
.nyc_output
|
|
||||||
.grunt
|
|
||||||
bower_components
|
|
||||||
.lock-wscript
|
.lock-wscript
|
||||||
build/Release
|
|
||||||
|
# Compiled binary addons (https://nodejs.org/api/addons.html)
|
||||||
|
build/
|
||||||
|
|
||||||
|
# Dependency directories
|
||||||
node_modules/
|
node_modules/
|
||||||
jspm_packages/
|
jspm_packages/
|
||||||
typings/
|
|
||||||
|
# Optional npm cache directory
|
||||||
.npm
|
.npm
|
||||||
|
|
||||||
|
# Optional eslint cache
|
||||||
.eslintcache
|
.eslintcache
|
||||||
|
|
||||||
|
# Optional stylelint cache
|
||||||
|
.stylelintcache
|
||||||
|
|
||||||
|
# Microbundle cache
|
||||||
|
.rpt2_cache/
|
||||||
|
.rts2_cache_cjs/
|
||||||
|
.rts2_cache_es/
|
||||||
|
.rts2_cache_umd/
|
||||||
|
|
||||||
|
# Optional REPL history
|
||||||
.node_repl_history
|
.node_repl_history
|
||||||
|
|
||||||
|
# Output of 'npm pack'
|
||||||
*.tgz
|
*.tgz
|
||||||
|
|
||||||
|
# Yarn Integrity file
|
||||||
.yarn-integrity
|
.yarn-integrity
|
||||||
.next
|
|
||||||
.ftpconfig
|
# dotenv environment variable files
|
||||||
coverage.lcov
|
.env
|
||||||
bannedusers.json
|
.env.development.local
|
||||||
*.code-workspace
|
.env.test.local
|
||||||
todo.txt
|
.env.production.local
|
||||||
.vscode/
|
.env.local
|
||||||
migratedb.js
|
|
||||||
processed.txt
|
# Gatsby files
|
||||||
data.sqlite
|
.cache/
|
||||||
|
# Comment in the public line in if your project uses Gatsby and not Next.js
|
||||||
|
# https://nextjs.org/blog/next-9-1#public-directory-support
|
||||||
|
# public
|
||||||
|
|
||||||
|
# vuepress v2.x temp and cache directory
|
||||||
|
.temp
|
||||||
.cache
|
.cache
|
||||||
|
|
||||||
|
# Stores VSCode versions used for testing VSCode extensions
|
||||||
|
.vscode-test
|
||||||
|
|
||||||
|
# yarn v2
|
||||||
|
.yarn/cache
|
||||||
|
.yarn/unplugged
|
||||||
|
.yarn/build-state.yml
|
||||||
|
.yarn/install-state.gz
|
||||||
|
.pnp.*
|
||||||
|
|
||||||
|
# Prerequisites
|
||||||
|
*.d
|
||||||
|
|
||||||
|
# Compiled Object files
|
||||||
|
*.slo
|
||||||
|
*.lo
|
||||||
|
*.o
|
||||||
|
*.obj
|
||||||
|
|
||||||
|
# Precompiled Headers
|
||||||
|
*.gch
|
||||||
|
*.pch
|
||||||
|
|
||||||
|
# Compiled Dynamic libraries
|
||||||
|
*.so
|
||||||
|
*.dylib
|
||||||
|
*.dll
|
||||||
|
|
||||||
|
# Compiled Static libraries
|
||||||
|
*.lai
|
||||||
|
*.la
|
||||||
|
*.a
|
||||||
|
*.lib
|
||||||
|
|
||||||
|
# Executables
|
||||||
|
*.exe
|
||||||
|
*.out
|
||||||
|
*.app
|
||||||
|
|
||||||
|
# Debugging
|
||||||
|
*.heap
|
||||||
|
*.out.*
|
||||||
|
|
||||||
|
# vscode stuff
|
||||||
|
.vscode
|
||||||
|
*.code-workspace
|
||||||
|
|
||||||
|
# Databases
|
||||||
|
data/
|
||||||
|
*.sqlite
|
||||||
|
|
||||||
|
# Azure Functions artifacts
|
||||||
|
bin
|
||||||
|
obj
|
||||||
|
appsettings.json
|
||||||
|
local.settings.json
|
||||||
|
|
||||||
|
# Azurite artifacts
|
||||||
|
__blobstorage__
|
||||||
|
__queuestorage__
|
||||||
|
__azurite_db*__.json
|
|
@ -25,7 +25,7 @@ class InfoCommand extends Command {
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "📝 Credits:",
|
name: "📝 Credits:",
|
||||||
value: "Bot by **[Essem](https://essem.space)** and **[various contributors](https://github.com/esmBot/esmBot/graphs/contributors)**\nIcon by **[MintBurrow](https://twitter.com/MintBurrow)**"
|
value: "Bot by **[Essem](https://essem.space)** and **[various contributors](https://github.com/esmBot/esmBot/graphs/contributors)**\nLogo by **[MintBurrow](https://twitter.com/MintBurrow)**"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "💬 Total Servers:",
|
name: "💬 Total Servers:",
|
||||||
|
|
|
@ -2,7 +2,7 @@ import ImageCommand from "../../classes/imageCommand.js";
|
||||||
|
|
||||||
class NineGagCommand extends ImageCommand {
|
class NineGagCommand extends ImageCommand {
|
||||||
params = {
|
params = {
|
||||||
water: "./assets/images/9gag.png",
|
water: "assets/images/9gag.png",
|
||||||
gravity: 6
|
gravity: 6
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,7 @@ import ImageCommand from "../../classes/imageCommand.js";
|
||||||
|
|
||||||
class AVSCommand extends ImageCommand {
|
class AVSCommand extends ImageCommand {
|
||||||
params = {
|
params = {
|
||||||
water: "./assets/images/avs4you.png",
|
water: "assets/images/avs4you.png",
|
||||||
gravity: 5,
|
gravity: 5,
|
||||||
resize: true
|
resize: true
|
||||||
};
|
};
|
||||||
|
|
|
@ -2,7 +2,7 @@ import ImageCommand from "../../classes/imageCommand.js";
|
||||||
|
|
||||||
class BandicamCommand extends ImageCommand {
|
class BandicamCommand extends ImageCommand {
|
||||||
params = {
|
params = {
|
||||||
water: "./assets/images/bandicam.png",
|
water: "assets/images/bandicam.png",
|
||||||
gravity: 2,
|
gravity: 2,
|
||||||
resize: true
|
resize: true
|
||||||
};
|
};
|
||||||
|
|
|
@ -2,7 +2,7 @@ import ImageCommand from "../../classes/imageCommand.js";
|
||||||
|
|
||||||
class DeviantArtCommand extends ImageCommand {
|
class DeviantArtCommand extends ImageCommand {
|
||||||
params = {
|
params = {
|
||||||
water: "./assets/images/deviantart.png",
|
water: "assets/images/deviantart.png",
|
||||||
gravity: 5,
|
gravity: 5,
|
||||||
resize: true
|
resize: true
|
||||||
};
|
};
|
||||||
|
|
|
@ -10,14 +10,14 @@ class FlagCommand extends ImageCommand {
|
||||||
const text = this.type === "classic" ? this.args[0] : this.options.text;
|
const text = this.type === "classic" ? this.args[0] : this.options.text;
|
||||||
if (!text.match(emojiRegex)) return false;
|
if (!text.match(emojiRegex)) return false;
|
||||||
const flag = emoji.unemojify(text).replaceAll(":", "").replace("flag-", "");
|
const flag = emoji.unemojify(text).replaceAll(":", "").replace("flag-", "");
|
||||||
let path = `./assets/images/region-flags/png/${flag.toUpperCase()}.png`;
|
let path = `assets/images/region-flags/png/${flag.toUpperCase()}.png`;
|
||||||
if (flag === "pirate_flag") path = "./assets/images/pirateflag.png";
|
if (flag === "pirate_flag") path = "assets/images/pirateflag.png";
|
||||||
if (flag === "rainbow-flag") path = "./assets/images/rainbowflag.png";
|
if (flag === "rainbow-flag") path = "assets/images/rainbowflag.png";
|
||||||
if (flag === "checkered_flag") path = "./assets/images/checkeredflag.png";
|
if (flag === "checkered_flag") path = "assets/images/checkeredflag.png";
|
||||||
if (flag === "transgender_flag") path = "./assets/images/transflag.png";
|
if (flag === "transgender_flag") path = "assets/images/transflag.png";
|
||||||
if (text === "🏴") path = "./assets/images/region-flags/png/GB-SCT.png";
|
if (text === "🏴") path = "assets/images/region-flags/png/GB-SCT.png";
|
||||||
if (text === "🏴") path = "./assets/images/region-flags/png/GB-WLS.png";
|
if (text === "🏴") path = "assets/images/region-flags/png/GB-WLS.png";
|
||||||
if (text === "🏴") path = "./assets/images/region-flags/png/GB-ENG.png";
|
if (text === "🏴") path = "assets/images/region-flags/png/GB-ENG.png";
|
||||||
try {
|
try {
|
||||||
await fs.promises.access(path);
|
await fs.promises.access(path);
|
||||||
this.flagPath = path;
|
this.flagPath = path;
|
||||||
|
|
|
@ -2,7 +2,7 @@ import ImageCommand from "../../classes/imageCommand.js";
|
||||||
|
|
||||||
class FunkyCommand extends ImageCommand {
|
class FunkyCommand extends ImageCommand {
|
||||||
params = {
|
params = {
|
||||||
water: "./assets/images/funky.png",
|
water: "assets/images/funky.png",
|
||||||
gravity: 3,
|
gravity: 3,
|
||||||
resize: true
|
resize: true
|
||||||
};
|
};
|
||||||
|
|
|
@ -2,7 +2,7 @@ import ImageCommand from "../../classes/imageCommand.js";
|
||||||
|
|
||||||
class HypercamCommand extends ImageCommand {
|
class HypercamCommand extends ImageCommand {
|
||||||
params = {
|
params = {
|
||||||
water: "./assets/images/hypercam.png",
|
water: "assets/images/hypercam.png",
|
||||||
gravity: 1,
|
gravity: 1,
|
||||||
resize: true
|
resize: true
|
||||||
};
|
};
|
||||||
|
|
|
@ -2,7 +2,7 @@ import ImageCommand from "../../classes/imageCommand.js";
|
||||||
|
|
||||||
class iFunnyCommand extends ImageCommand {
|
class iFunnyCommand extends ImageCommand {
|
||||||
params = {
|
params = {
|
||||||
water: "./assets/images/ifunny.png",
|
water: "assets/images/ifunny.png",
|
||||||
gravity: 8,
|
gravity: 8,
|
||||||
resize: true,
|
resize: true,
|
||||||
append: true
|
append: true
|
||||||
|
|
|
@ -2,7 +2,7 @@ import ImageCommand from "../../classes/imageCommand.js";
|
||||||
|
|
||||||
class KineMasterCommand extends ImageCommand {
|
class KineMasterCommand extends ImageCommand {
|
||||||
params = {
|
params = {
|
||||||
water: "./assets/images/kinemaster.png",
|
water: "assets/images/kinemaster.png",
|
||||||
gravity: 3,
|
gravity: 3,
|
||||||
resize: true
|
resize: true
|
||||||
};
|
};
|
||||||
|
|
|
@ -2,7 +2,7 @@ import ImageCommand from "../../classes/imageCommand.js";
|
||||||
|
|
||||||
class MemeCenterCommand extends ImageCommand {
|
class MemeCenterCommand extends ImageCommand {
|
||||||
params = {
|
params = {
|
||||||
water: "./assets/images/memecenter.png",
|
water: "assets/images/memecenter.png",
|
||||||
gravity: 9,
|
gravity: 9,
|
||||||
mc: true
|
mc: true
|
||||||
};
|
};
|
||||||
|
|
|
@ -2,7 +2,7 @@ import ImageCommand from "../../classes/imageCommand.js";
|
||||||
|
|
||||||
class ShutterstockCommand extends ImageCommand {
|
class ShutterstockCommand extends ImageCommand {
|
||||||
params = {
|
params = {
|
||||||
water: "./assets/images/shutterstock.png",
|
water: "assets/images/shutterstock.png",
|
||||||
gravity: 5,
|
gravity: 5,
|
||||||
resize: true
|
resize: true
|
||||||
};
|
};
|
||||||
|
|
|
@ -2,7 +2,7 @@ import ImageCommand from "../../classes/imageCommand.js";
|
||||||
|
|
||||||
class SpeechBubbleCommand extends ImageCommand {
|
class SpeechBubbleCommand extends ImageCommand {
|
||||||
params = {
|
params = {
|
||||||
water: "./assets/images/speechbubble.png",
|
water: "assets/images/speechbubble.png",
|
||||||
gravity: "north",
|
gravity: "north",
|
||||||
resize: true,
|
resize: true,
|
||||||
yscale: 0.2,
|
yscale: 0.2,
|
||||||
|
|
|
@ -15,6 +15,7 @@ Napi::Value Flag(const Napi::CallbackInfo &info) {
|
||||||
Napi::Buffer<char> data = obj.Get("data").As<Napi::Buffer<char>>();
|
Napi::Buffer<char> data = obj.Get("data").As<Napi::Buffer<char>>();
|
||||||
string overlay = obj.Get("overlay").As<Napi::String>().Utf8Value();
|
string overlay = obj.Get("overlay").As<Napi::String>().Utf8Value();
|
||||||
string type = obj.Get("type").As<Napi::String>().Utf8Value();
|
string type = obj.Get("type").As<Napi::String>().Utf8Value();
|
||||||
|
string basePath = obj.Get("basePath").As<Napi::String>().Utf8Value();
|
||||||
int delay =
|
int delay =
|
||||||
obj.Has("delay") ? obj.Get("delay").As<Napi::Number>().Int32Value() : 0;
|
obj.Has("delay") ? obj.Get("delay").As<Napi::Number>().Int32Value() : 0;
|
||||||
|
|
||||||
|
@ -31,7 +32,8 @@ Napi::Value Flag(const Napi::CallbackInfo &info) {
|
||||||
} catch (Magick::Warning &warning) {
|
} catch (Magick::Warning &warning) {
|
||||||
cerr << "Warning: " << warning.what() << endl;
|
cerr << "Warning: " << warning.what() << endl;
|
||||||
}
|
}
|
||||||
watermark.read(overlay);
|
string assetPath = basePath + overlay;
|
||||||
|
watermark.read(assetPath);
|
||||||
watermark.alphaChannel(Magick::SetAlphaChannel);
|
watermark.alphaChannel(Magick::SetAlphaChannel);
|
||||||
watermark.evaluate(Magick::AlphaChannel, Magick::MultiplyEvaluateOperator,
|
watermark.evaluate(Magick::AlphaChannel, Magick::MultiplyEvaluateOperator,
|
||||||
0.5);
|
0.5);
|
||||||
|
|
|
@ -14,6 +14,7 @@ Napi::Value Gamexplain(const Napi::CallbackInfo &info) {
|
||||||
Napi::Object obj = info[0].As<Napi::Object>();
|
Napi::Object obj = info[0].As<Napi::Object>();
|
||||||
Napi::Buffer<char> data = obj.Get("data").As<Napi::Buffer<char>>();
|
Napi::Buffer<char> data = obj.Get("data").As<Napi::Buffer<char>>();
|
||||||
string type = obj.Get("type").As<Napi::String>().Utf8Value();
|
string type = obj.Get("type").As<Napi::String>().Utf8Value();
|
||||||
|
string basePath = obj.Get("basePath").As<Napi::String>().Utf8Value();
|
||||||
int delay =
|
int delay =
|
||||||
obj.Has("delay") ? obj.Get("delay").As<Napi::Number>().Int32Value() : 0;
|
obj.Has("delay") ? obj.Get("delay").As<Napi::Number>().Int32Value() : 0;
|
||||||
|
|
||||||
|
@ -30,7 +31,8 @@ Napi::Value Gamexplain(const Napi::CallbackInfo &info) {
|
||||||
} catch (Magick::Warning &warning) {
|
} catch (Magick::Warning &warning) {
|
||||||
cerr << "Warning: " << warning.what() << endl;
|
cerr << "Warning: " << warning.what() << endl;
|
||||||
}
|
}
|
||||||
watermark.read("./assets/images/gamexplain.png");
|
string assetPath = basePath + "assets/images/gamexplain.png";
|
||||||
|
watermark.read(assetPath);
|
||||||
coalesceImages(&coalesced, frames.begin(), frames.end());
|
coalesceImages(&coalesced, frames.begin(), frames.end());
|
||||||
|
|
||||||
for (Image &image : coalesced) {
|
for (Image &image : coalesced) {
|
||||||
|
|
|
@ -14,6 +14,7 @@ Napi::Value Globe(const Napi::CallbackInfo &info) {
|
||||||
Napi::Object obj = info[0].As<Napi::Object>();
|
Napi::Object obj = info[0].As<Napi::Object>();
|
||||||
Napi::Buffer<char> data = obj.Get("data").As<Napi::Buffer<char>>();
|
Napi::Buffer<char> data = obj.Get("data").As<Napi::Buffer<char>>();
|
||||||
string type = obj.Get("type").As<Napi::String>().Utf8Value();
|
string type = obj.Get("type").As<Napi::String>().Utf8Value();
|
||||||
|
string basePath = obj.Get("basePath").As<Napi::String>().Utf8Value();
|
||||||
int delay =
|
int delay =
|
||||||
obj.Has("delay") ? obj.Get("delay").As<Napi::Number>().Int32Value() : 0;
|
obj.Has("delay") ? obj.Get("delay").As<Napi::Number>().Int32Value() : 0;
|
||||||
|
|
||||||
|
@ -31,8 +32,8 @@ Napi::Value Globe(const Napi::CallbackInfo &info) {
|
||||||
} catch (Magick::Warning &warning) {
|
} catch (Magick::Warning &warning) {
|
||||||
cerr << "Warning: " << warning.what() << endl;
|
cerr << "Warning: " << warning.what() << endl;
|
||||||
}
|
}
|
||||||
distort.read("./assets/images/spheremap.png");
|
distort.read(basePath + "assets/images/spheremap.png");
|
||||||
overlay.read("./assets/images/sphere_overlay.png");
|
overlay.read(basePath + "assets/images/sphere_overlay.png");
|
||||||
coalesceImages(&coalesced, frames.begin(), frames.end());
|
coalesceImages(&coalesced, frames.begin(), frames.end());
|
||||||
|
|
||||||
if (type != "gif") {
|
if (type != "gif") {
|
||||||
|
|
|
@ -12,11 +12,13 @@ Napi::Value Homebrew(const Napi::CallbackInfo &info) {
|
||||||
try {
|
try {
|
||||||
Napi::Object obj = info[0].As<Napi::Object>();
|
Napi::Object obj = info[0].As<Napi::Object>();
|
||||||
string caption = obj.Get("caption").As<Napi::String>().Utf8Value();
|
string caption = obj.Get("caption").As<Napi::String>().Utf8Value();
|
||||||
|
string basePath = obj.Get("basePath").As<Napi::String>().Utf8Value();
|
||||||
|
|
||||||
Blob blob;
|
Blob blob;
|
||||||
|
|
||||||
Image image;
|
Image image;
|
||||||
image.read("./assets/images/hbc.png");
|
string assetPath = basePath + "assets/images/hbc.png";
|
||||||
|
image.read(assetPath);
|
||||||
image.textGravity(Magick::CenterGravity);
|
image.textGravity(Magick::CenterGravity);
|
||||||
image.font("./assets/hbc.ttf");
|
image.font("./assets/hbc.ttf");
|
||||||
image.textKerning(-5);
|
image.textKerning(-5);
|
||||||
|
|
|
@ -14,6 +14,7 @@ Napi::Value Reddit(const Napi::CallbackInfo &info) {
|
||||||
Napi::Buffer<char> data = obj.Get("data").As<Napi::Buffer<char>>();
|
Napi::Buffer<char> data = obj.Get("data").As<Napi::Buffer<char>>();
|
||||||
string text = obj.Get("caption").As<Napi::String>().Utf8Value();
|
string text = obj.Get("caption").As<Napi::String>().Utf8Value();
|
||||||
string type = obj.Get("type").As<Napi::String>().Utf8Value();
|
string type = obj.Get("type").As<Napi::String>().Utf8Value();
|
||||||
|
string basePath = obj.Get("basePath").As<Napi::String>().Utf8Value();
|
||||||
int delay =
|
int delay =
|
||||||
obj.Has("delay") ? obj.Get("delay").As<Napi::Number>().Int32Value() : 0;
|
obj.Has("delay") ? obj.Get("delay").As<Napi::Number>().Int32Value() : 0;
|
||||||
|
|
||||||
|
@ -32,7 +33,7 @@ Napi::Value Reddit(const Napi::CallbackInfo &info) {
|
||||||
cerr << "Warning: " << warning.what() << endl;
|
cerr << "Warning: " << warning.what() << endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
watermark.read("./assets/images/reddit.png");
|
watermark.read(basePath + "assets/images/reddit.png");
|
||||||
text_image.textGravity(Magick::WestGravity);
|
text_image.textGravity(Magick::WestGravity);
|
||||||
text_image.font("Roboto");
|
text_image.font("Roboto");
|
||||||
text_image.fontPointsize(47);
|
text_image.fontPointsize(47);
|
||||||
|
|
|
@ -14,6 +14,7 @@ Napi::Value Retro(const Napi::CallbackInfo &info) {
|
||||||
string line1 = obj.Get("line1").As<Napi::String>().Utf8Value();
|
string line1 = obj.Get("line1").As<Napi::String>().Utf8Value();
|
||||||
string line2 = obj.Get("line2").As<Napi::String>().Utf8Value();
|
string line2 = obj.Get("line2").As<Napi::String>().Utf8Value();
|
||||||
string line3 = obj.Get("line3").As<Napi::String>().Utf8Value();
|
string line3 = obj.Get("line3").As<Napi::String>().Utf8Value();
|
||||||
|
string basePath = obj.Get("basePath").As<Napi::String>().Utf8Value();
|
||||||
|
|
||||||
Blob blob;
|
Blob blob;
|
||||||
|
|
||||||
|
@ -22,7 +23,7 @@ Napi::Value Retro(const Napi::CallbackInfo &info) {
|
||||||
Image line2_text;
|
Image line2_text;
|
||||||
Image line3_text;
|
Image line3_text;
|
||||||
|
|
||||||
image.read("./assets/images/retro.png");
|
image.read(basePath + "assets/images/retro.png");
|
||||||
|
|
||||||
line2_text.backgroundColor("none");
|
line2_text.backgroundColor("none");
|
||||||
line2_text.fontPointsize(128);
|
line2_text.fontPointsize(128);
|
||||||
|
|
|
@ -14,6 +14,7 @@ Napi::Value Scott(const Napi::CallbackInfo &info) {
|
||||||
Napi::Object obj = info[0].As<Napi::Object>();
|
Napi::Object obj = info[0].As<Napi::Object>();
|
||||||
Napi::Buffer<char> data = obj.Get("data").As<Napi::Buffer<char>>();
|
Napi::Buffer<char> data = obj.Get("data").As<Napi::Buffer<char>>();
|
||||||
string type = obj.Get("type").As<Napi::String>().Utf8Value();
|
string type = obj.Get("type").As<Napi::String>().Utf8Value();
|
||||||
|
string basePath = obj.Get("basePath").As<Napi::String>().Utf8Value();
|
||||||
int delay =
|
int delay =
|
||||||
obj.Has("delay") ? obj.Get("delay").As<Napi::Number>().Int32Value() : 0;
|
obj.Has("delay") ? obj.Get("delay").As<Napi::Number>().Int32Value() : 0;
|
||||||
|
|
||||||
|
@ -30,7 +31,7 @@ Napi::Value Scott(const Napi::CallbackInfo &info) {
|
||||||
} catch (Magick::Warning &warning) {
|
} catch (Magick::Warning &warning) {
|
||||||
cerr << "Warning: " << warning.what() << endl;
|
cerr << "Warning: " << warning.what() << endl;
|
||||||
}
|
}
|
||||||
watermark.read("./assets/images/scott.png");
|
watermark.read(basePath + "assets/images/scott.png");
|
||||||
coalesceImages(&coalesced, frames.begin(), frames.end());
|
coalesceImages(&coalesced, frames.begin(), frames.end());
|
||||||
|
|
||||||
for (Image &image : coalesced) {
|
for (Image &image : coalesced) {
|
||||||
|
|
|
@ -12,6 +12,7 @@ Napi::Value Sonic(const Napi::CallbackInfo &info) {
|
||||||
try {
|
try {
|
||||||
Napi::Object obj = info[0].As<Napi::Object>();
|
Napi::Object obj = info[0].As<Napi::Object>();
|
||||||
string text = obj.Get("text").As<Napi::String>().Utf8Value();
|
string text = obj.Get("text").As<Napi::String>().Utf8Value();
|
||||||
|
string basePath = obj.Get("basePath").As<Napi::String>().Utf8Value();
|
||||||
|
|
||||||
Blob blob;
|
Blob blob;
|
||||||
|
|
||||||
|
@ -24,7 +25,7 @@ Napi::Value Sonic(const Napi::CallbackInfo &info) {
|
||||||
text_image.read("pango:<span foreground='white'>" + text + "</span>");
|
text_image.read("pango:<span foreground='white'>" + text + "</span>");
|
||||||
text_image.resize(Geometry(474, 332));
|
text_image.resize(Geometry(474, 332));
|
||||||
text_image.extent(Geometry("1024x538-435-145"), Magick::CenterGravity);
|
text_image.extent(Geometry("1024x538-435-145"), Magick::CenterGravity);
|
||||||
image.read("./assets/images/sonic.jpg");
|
image.read(basePath + "assets/images/sonic.jpg");
|
||||||
image.composite(text_image, Geometry("+160+10"), Magick::OverCompositeOp);
|
image.composite(text_image, Geometry("+160+10"), Magick::OverCompositeOp);
|
||||||
image.magick("PNG");
|
image.magick("PNG");
|
||||||
image.write(&blob);
|
image.write(&blob);
|
||||||
|
|
|
@ -26,6 +26,7 @@ Napi::Value Watermark(const Napi::CallbackInfo &info) {
|
||||||
? obj.Get("append").As<Napi::Boolean>().Value()
|
? obj.Get("append").As<Napi::Boolean>().Value()
|
||||||
: false;
|
: false;
|
||||||
bool mc = obj.Has("mc") ? obj.Get("mc").As<Napi::Boolean>().Value() : false;
|
bool mc = obj.Has("mc") ? obj.Get("mc").As<Napi::Boolean>().Value() : false;
|
||||||
|
string basePath = obj.Get("basePath").As<Napi::String>().Utf8Value();
|
||||||
string type = obj.Get("type").As<Napi::String>().Utf8Value();
|
string type = obj.Get("type").As<Napi::String>().Utf8Value();
|
||||||
int delay =
|
int delay =
|
||||||
obj.Has("delay") ? obj.Get("delay").As<Napi::Number>().Int32Value() : 0;
|
obj.Has("delay") ? obj.Get("delay").As<Napi::Number>().Int32Value() : 0;
|
||||||
|
@ -43,7 +44,8 @@ Napi::Value Watermark(const Napi::CallbackInfo &info) {
|
||||||
} catch (Magick::Warning &warning) {
|
} catch (Magick::Warning &warning) {
|
||||||
cerr << "Warning: " << warning.what() << endl;
|
cerr << "Warning: " << warning.what() << endl;
|
||||||
}
|
}
|
||||||
watermark.read(water);
|
string merged = basePath + water;
|
||||||
|
watermark.read(merged);
|
||||||
if (resize && append) {
|
if (resize && append) {
|
||||||
string query(to_string(frames.front().baseColumns()) + "x");
|
string query(to_string(frames.front().baseColumns()) + "x");
|
||||||
watermark.scale(Geometry(query));
|
watermark.scale(Geometry(query));
|
||||||
|
|
|
@ -14,6 +14,7 @@ Napi::Value Wdt(const Napi::CallbackInfo &info) {
|
||||||
Napi::Object obj = info[0].As<Napi::Object>();
|
Napi::Object obj = info[0].As<Napi::Object>();
|
||||||
Napi::Buffer<char> data = obj.Get("data").As<Napi::Buffer<char>>();
|
Napi::Buffer<char> data = obj.Get("data").As<Napi::Buffer<char>>();
|
||||||
string type = obj.Get("type").As<Napi::String>().Utf8Value();
|
string type = obj.Get("type").As<Napi::String>().Utf8Value();
|
||||||
|
string basePath = obj.Get("basePath").As<Napi::String>().Utf8Value();
|
||||||
int delay =
|
int delay =
|
||||||
obj.Has("delay") ? obj.Get("delay").As<Napi::Number>().Int32Value() : 0;
|
obj.Has("delay") ? obj.Get("delay").As<Napi::Number>().Int32Value() : 0;
|
||||||
|
|
||||||
|
@ -30,7 +31,7 @@ Napi::Value Wdt(const Napi::CallbackInfo &info) {
|
||||||
} catch (Magick::Warning &warning) {
|
} catch (Magick::Warning &warning) {
|
||||||
cerr << "Warning: " << warning.what() << endl;
|
cerr << "Warning: " << warning.what() << endl;
|
||||||
}
|
}
|
||||||
watermark.read("./assets/images/whodidthis.png");
|
watermark.read(basePath + "assets/images/whodidthis.png");
|
||||||
coalesceImages(&coalesced, frames.begin(), frames.end());
|
coalesceImages(&coalesced, frames.begin(), frames.end());
|
||||||
|
|
||||||
for (Image &image : coalesced) {
|
for (Image &image : coalesced) {
|
||||||
|
|
|
@ -13,6 +13,7 @@ Napi::Value Zamn(const Napi::CallbackInfo &info) {
|
||||||
Napi::Object obj = info[0].As<Napi::Object>();
|
Napi::Object obj = info[0].As<Napi::Object>();
|
||||||
Napi::Buffer<char> data = obj.Get("data").As<Napi::Buffer<char>>();
|
Napi::Buffer<char> data = obj.Get("data").As<Napi::Buffer<char>>();
|
||||||
string type = obj.Get("type").As<Napi::String>().Utf8Value();
|
string type = obj.Get("type").As<Napi::String>().Utf8Value();
|
||||||
|
string basePath = obj.Get("basePath").As<Napi::String>().Utf8Value();
|
||||||
int delay =
|
int delay =
|
||||||
obj.Has("delay") ? obj.Get("delay").As<Napi::Number>().Int32Value() : 0;
|
obj.Has("delay") ? obj.Get("delay").As<Napi::Number>().Int32Value() : 0;
|
||||||
|
|
||||||
|
@ -23,7 +24,7 @@ Napi::Value Zamn(const Napi::CallbackInfo &info) {
|
||||||
list<Image> mid;
|
list<Image> mid;
|
||||||
Image watermark;
|
Image watermark;
|
||||||
readImages(&frames, Blob(data.Data(), data.Length()));
|
readImages(&frames, Blob(data.Data(), data.Length()));
|
||||||
watermark.read("./assets/images/zamn.png");
|
watermark.read(basePath + "assets/images/zamn.png");
|
||||||
coalesceImages(&coalesced, frames.begin(), frames.end());
|
coalesceImages(&coalesced, frames.begin(), frames.end());
|
||||||
|
|
||||||
for (Image &image : coalesced) {
|
for (Image &image : coalesced) {
|
||||||
|
|
|
@ -1,10 +1,13 @@
|
||||||
import { createRequire } from "module";
|
import { createRequire } from "module";
|
||||||
import { isMainThread, parentPort, workerData } from "worker_threads";
|
import { isMainThread, parentPort, workerData } from "worker_threads";
|
||||||
import fetch from "node-fetch";
|
import fetch from "node-fetch";
|
||||||
|
import path from "path";
|
||||||
|
import { fileURLToPath } from "url";
|
||||||
|
|
||||||
const nodeRequire = createRequire(import.meta.url);
|
const nodeRequire = createRequire(import.meta.url);
|
||||||
|
|
||||||
const magick = nodeRequire(`../build/${process.env.DEBUG && process.env.DEBUG === "true" ? "Debug" : "Release"}/image.node`);
|
const relPath = `../build/${process.env.DEBUG && process.env.DEBUG === "true" ? "Debug" : "Release"}/image.node`;
|
||||||
|
const magick = nodeRequire(relPath);
|
||||||
|
|
||||||
const enumMap = {
|
const enumMap = {
|
||||||
"forget": 0,
|
"forget": 0,
|
||||||
|
@ -42,6 +45,7 @@ export default function run(object) {
|
||||||
objectWithFixedType.gravity = enumMap[objectWithFixedType.gravity];
|
objectWithFixedType.gravity = enumMap[objectWithFixedType.gravity];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
objectWithFixedType.basePath = path.join(path.dirname(fileURLToPath(import.meta.url)), "../");
|
||||||
try {
|
try {
|
||||||
const result = magick[object.cmd](objectWithFixedType);
|
const result = magick[object.cmd](objectWithFixedType);
|
||||||
const returnObject = {
|
const returnObject = {
|
||||||
|
|
|
@ -5,6 +5,9 @@ import path from "path";
|
||||||
import { fileURLToPath } from "url";
|
import { fileURLToPath } from "url";
|
||||||
import { Worker } from "worker_threads";
|
import { Worker } from "worker_threads";
|
||||||
import { createRequire } from "module";
|
import { createRequire } from "module";
|
||||||
|
import { createServer } from "http";
|
||||||
|
import fetch from "node-fetch";
|
||||||
|
import EventEmitter from "events";
|
||||||
|
|
||||||
// only requiring this to work around an issue regarding worker threads
|
// only requiring this to work around an issue regarding worker threads
|
||||||
const nodeRequire = createRequire(import.meta.url);
|
const nodeRequire = createRequire(import.meta.url);
|
||||||
|
@ -18,11 +21,14 @@ class ImageWorker extends BaseServiceWorker {
|
||||||
|
|
||||||
console.info = (str) => this.ipc.sendToAdmiral("info", str);
|
console.info = (str) => this.ipc.sendToAdmiral("info", str);
|
||||||
|
|
||||||
if (process.env.API === "true") {
|
if (process.env.API_TYPE === "ws") {
|
||||||
this.jobs = {};
|
|
||||||
this.connections = new Map();
|
this.connections = new Map();
|
||||||
this.servers = JSON.parse(fs.readFileSync(new URL("../../servers.json", import.meta.url), { encoding: "utf8" })).image;
|
this.servers = JSON.parse(fs.readFileSync(new URL("../../servers.json", import.meta.url), { encoding: "utf8" })).image;
|
||||||
this.nextID = 0;
|
this.nextID = 0;
|
||||||
|
} else if (process.env.API_TYPE === "azure") {
|
||||||
|
this.jobs = new Map();
|
||||||
|
this.webhook = createServer();
|
||||||
|
this.port = parseInt(process.env.WEBHOOK_PORT) || 3763;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.begin().then(() => this.serviceReady());
|
this.begin().then(() => this.serviceReady());
|
||||||
|
@ -30,7 +36,7 @@ class ImageWorker extends BaseServiceWorker {
|
||||||
|
|
||||||
async begin() {
|
async begin() {
|
||||||
// connect to image api if enabled
|
// connect to image api if enabled
|
||||||
if (process.env.API === "true") {
|
if (process.env.API_TYPE === "ws") {
|
||||||
for (const server of this.servers) {
|
for (const server of this.servers) {
|
||||||
try {
|
try {
|
||||||
await this.connect(server.server, server.auth);
|
await this.connect(server.server, server.auth);
|
||||||
|
@ -38,6 +44,73 @@ class ImageWorker extends BaseServiceWorker {
|
||||||
logger.error(e);
|
logger.error(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} else if (process.env.API_TYPE === "azure") {
|
||||||
|
this.webhook.on("request", async (req, res) => {
|
||||||
|
if (req.method !== "POST") {
|
||||||
|
res.statusCode = 405;
|
||||||
|
return res.end("405 Method Not Allowed");
|
||||||
|
}
|
||||||
|
if (process.env.AZURE_PASS && req.headers.authorization !== process.env.AZURE_PASS) {
|
||||||
|
res.statusCode = 401;
|
||||||
|
return res.end("401 Unauthorized");
|
||||||
|
}
|
||||||
|
const reqUrl = new URL(req.url, `http://${req.headers.host}`);
|
||||||
|
if (reqUrl.pathname === "/callback") {
|
||||||
|
try {
|
||||||
|
const chunks = [];
|
||||||
|
req.on("data", (data) => {
|
||||||
|
chunks.push(data);
|
||||||
|
});
|
||||||
|
req.once("end", () => {
|
||||||
|
if (this.jobs.has(req.headers["x-azure-id"])) {
|
||||||
|
try {
|
||||||
|
const error = JSON.parse(Buffer.concat(chunks).toString());
|
||||||
|
if (error.error) this.jobs.get(req.headers["x-azure-id"]).emit("error", new Error(error.message));
|
||||||
|
} catch {
|
||||||
|
// no-op
|
||||||
|
}
|
||||||
|
const contentType = req.headers["content-type"];
|
||||||
|
let type;
|
||||||
|
switch (contentType) {
|
||||||
|
case "image/gif":
|
||||||
|
type = "gif";
|
||||||
|
break;
|
||||||
|
case "image/png":
|
||||||
|
type = "png";
|
||||||
|
break;
|
||||||
|
case "image/jpeg":
|
||||||
|
type = "jpg";
|
||||||
|
break;
|
||||||
|
case "image/webp":
|
||||||
|
type = "webp";
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
type = contentType;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
this.jobs.get(req.headers["x-azure-id"]).emit("image", { buffer: Buffer.concat(chunks), type });
|
||||||
|
return res.end("OK");
|
||||||
|
} else {
|
||||||
|
res.statusCode = 409;
|
||||||
|
return res.end("409 Conflict");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} catch (e) {
|
||||||
|
logger.error("An error occurred while processing a webhook request: ", e);
|
||||||
|
res.statusCode = 500;
|
||||||
|
return res.end("500 Internal Server Error");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
res.statusCode = 404;
|
||||||
|
return res.end("404 Not Found");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
this.webhook.on("error", (e) => {
|
||||||
|
logger.error("An error occurred on the Azure webhook: ", e);
|
||||||
|
});
|
||||||
|
this.webhook.listen(this.port, () => {
|
||||||
|
logger.log(`Azure HTTP webhook listening on port ${this.port}`);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -49,7 +122,7 @@ class ImageWorker extends BaseServiceWorker {
|
||||||
|
|
||||||
async getRunning() {
|
async getRunning() {
|
||||||
const statuses = [];
|
const statuses = [];
|
||||||
if (process.env.API === "true") {
|
if (process.env.API_TYPE === "ws") {
|
||||||
for (const [address, connection] of this.connections) {
|
for (const [address, connection] of this.connections) {
|
||||||
if (connection.conn.readyState !== 0 && connection.conn.readyState !== 1) {
|
if (connection.conn.readyState !== 0 && connection.conn.readyState !== 1) {
|
||||||
continue;
|
continue;
|
||||||
|
@ -115,8 +188,17 @@ class ImageWorker extends BaseServiceWorker {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
waitForAzure(event) {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
event.once("image", (data) => {
|
||||||
|
resolve(data);
|
||||||
|
});
|
||||||
|
event.once("error", reject);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
async run(object) {
|
async run(object) {
|
||||||
if (process.env.API === "true") {
|
if (process.env.API_TYPE === "ws") {
|
||||||
let num = this.nextID++;
|
let num = this.nextID++;
|
||||||
if (num > 4294967295) num = this.nextID = 0;
|
if (num > 4294967295) num = this.nextID = 0;
|
||||||
for (let i = 0; i < 3; i++) {
|
for (let i = 0; i < 3; i++) {
|
||||||
|
@ -135,6 +217,12 @@ class ImageWorker extends BaseServiceWorker {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} else if (process.env.API_TYPE === "azure") {
|
||||||
|
object.callback = `${process.env.AZURE_CALLBACK_URL}:${this.port}/callback`;
|
||||||
|
const response = await fetch(`${process.env.AZURE_URL}/api/orchestrators/ImageOrchestrator`, { method: "POST", body: JSON.stringify(object) }).then(r => r.json());
|
||||||
|
const event = new EventEmitter();
|
||||||
|
this.jobs.set(response.id, event);
|
||||||
|
return await this.waitForAzure(event);
|
||||||
} else {
|
} else {
|
||||||
// Called from command (not using image API)
|
// Called from command (not using image API)
|
||||||
const worker = new Worker(path.join(path.dirname(fileURLToPath(import.meta.url)), "../image-runner.js"), {
|
const worker = new Worker(path.join(path.dirname(fileURLToPath(import.meta.url)), "../image-runner.js"), {
|
||||||
|
|
|
@ -22,7 +22,7 @@ class PrometheusWorker extends BaseServiceWorker {
|
||||||
# HELP esmbot_shard_count Number of shards the bot has
|
# HELP esmbot_shard_count Number of shards the bot has
|
||||||
# TYPE esmbot_shard_count gauge
|
# TYPE esmbot_shard_count gauge
|
||||||
`);
|
`);
|
||||||
if (process.env.API === "true") {
|
if (process.env.API_TYPE === "ws") {
|
||||||
const servers = await this.ipc.serviceCommand("image", { type: "stats" }, true);
|
const servers = await this.ipc.serviceCommand("image", { type: "stats" }, true);
|
||||||
res.write(`# HELP esmbot_connected_workers Number of workers connected
|
res.write(`# HELP esmbot_connected_workers Number of workers connected
|
||||||
# TYPE esmbot_connected_workers gauge
|
# TYPE esmbot_connected_workers gauge
|
||||||
|
|
Loading…
Reference in New Issue