Remove NSFWJS

This commit is contained in:
lilyissillyyy
2026-02-17 17:38:40 -05:00
parent 183424e081
commit d83a1fb2b9
8 changed files with 3 additions and 93 deletions
+1 -3
View File
@@ -115,7 +115,7 @@ Only if you want to use the DECTalk command.
18. Start Xiao up!
## Commands
Total: 516
Total: 515
### Utility:
@@ -327,7 +327,6 @@ Total: 516
* **is-it-down:** Determines if a website is down or not.
* **levenshtein:** Determines the levenshtein distance between two strings.
* **name-gender:** Determines the gender of a name.
* **nsfw-image:** Determines if an image is NSFW.
* **nsfw-url:** Determines if a URL is NSFW.
* **parse-time:** Analyzes the time duration you provide and gives the result.
* **read-qr-code:** Reads a QR Code.
@@ -728,7 +727,6 @@ Total: 516
* [moment-timezone](https://www.npmjs.com/package/moment-timezone)
* [neopet-image-finder](https://www.npmjs.com/package/neopet-image-finder)
* [node-superfetch](https://www.npmjs.com/package/node-superfetch)
* [nsfwjs](https://www.npmjs.com/package/nsfwjs)
* [ntcjs](https://www.npmjs.com/package/ntcjs)
* [parse-domain](https://www.npmjs.com/package/parse-domain)
* [pokersolver](https://www.npmjs.com/package/pokersolver)
-8
View File
@@ -256,14 +256,6 @@ client.on('clientReady', async () => {
client.logger.error(`[ADULT SITES] Failed to fetch list\n${err.stack}`);
}
// Set up nsfwjs
try {
await client.tensorflow.loadNSFWJS();
client.logger.info('[NSFWJS] Loaded NSFWJS.');
} catch (err) {
client.logger.error(`[NSFWJS] Failed to load NSFWJS\n${err.stack}`);
}
// Set up face detection
try {
await client.tensorflow.loadFaceDetector();
-1
View File
@@ -44,7 +44,6 @@
"The `horse-race` command contains several references: real horse names, My Little Pony characters, and various pop culture jokes. Even a few Xiao jokes are snuck in there!",
"In `horse-race`, you will occasionally encounter horses named \"Donald Trump\" and \"Lily is Silly\". Be careful, as these aren't horses, their times are based on the actual human running the race!",
"Numerous commands use a massive 2,000,000 entry array to check for adult sites. Some _still_ fall through the cracks.",
"Numerous commands use an AI powered by Tensorflow to check for NSFW content. It is about 93% accurate.",
"The `ship` command will call you a narcissist if you test yourself with yourself.",
"Whenever Lily gets a real fortune cookie, she adds the fortune to the `fortune` command.",
"The `whos-that-pokemon` command will play a sound effect and the Pokémon's cry if both you and the bot are in a voice channel when the command is used.",
-45
View File
@@ -1,45 +0,0 @@
const Command = require('../../framework/Command');
const request = require('node-superfetch');
const { stripIndents } = require('common-tags');
const displayNames = {
Drawing: 'SFW (Drawing)',
Neutral: 'SFW',
Porn: 'NSFW',
Hentai: 'NSFW (Drawing)',
Sexy: 'Suggestive'
};
module.exports = class NsfwImageCommand extends Command {
constructor(client) {
super(client, {
name: 'nsfw-image',
aliases: ['nsfw', 'nsfw-img', 'img-nsfw', 'image-nsfw'],
group: 'analyze',
description: 'Determines if an image is NSFW.',
throttling: {
usages: 2,
duration: 30
},
args: [
{
key: 'image',
type: 'image-or-avatar',
avatarSize: 256
}
]
});
}
async run(msg, { image }) {
const { body } = await request.get(image);
const predictions = await this.client.tensorflow.isImageNSFW(body, false);
const formatted = predictions.map(result => {
const percentage = Math.round(result.probability * 100);
return `${percentage}% ${displayNames[result.className]}`;
});
return msg.reply(stripIndents`
**This image gives the following results:**
${formatted.join('\n')}
`);
}
};
-4
View File
@@ -39,10 +39,6 @@ module.exports = class ScreenshotCommand extends Command {
if (nsfw) return msg.reply('This site is NSFW.');
}
const { body } = await request.get(`https://image.thum.io/get/width/1920/crop/675/noanimate/${url.href}`);
if (!msg.channel.nsfw) {
const aiDetect = await this.client.tensorflow.isImageNSFW(body);
if (aiDetect) return msg.reply('This site isn\'t NSFW, but the resulting image was.');
}
return msg.say({ files: [{ attachment: body, name: 'screenshot.png' }] });
} catch (err) {
if (err.status === 404) return msg.say('Could not find any results. Invalid URL?');
+1 -6
View File
@@ -46,12 +46,7 @@ module.exports = class WikipediaCommand extends Command {
});
const data = body.query.pages[0];
if (data.missing) return msg.say('Could not find any results.');
let thumbnail = data.thumbnail ? data.thumbnail.source : null;
if (!msg.channel.nsfw && thumbnail) {
const img = await request.get(thumbnail);
const nsfw = await this.client.tensorflow.isImageNSFW(img.body);
if (nsfw) thumbnail = null;
}
const thumbnail = data.thumbnail ? data.thumbnail.source : null;
let fact = data.extract;
if (fact.length > 200) {
const facts = fact.split('.');
+1 -2
View File
@@ -1,6 +1,6 @@
{
"name": "xiao",
"version": "159.4.3",
"version": "160.0.0",
"description": "Your personal server companion.",
"main": "Xiao.js",
"scripts": {
@@ -67,7 +67,6 @@
"moment-timezone": "^0.6.0",
"neopet-image-finder": "^5.0.3",
"node-superfetch": "^0.3.5",
"nsfwjs": "^4.2.1",
"ntcjs": "^1.1.3",
"parse-domain": "^8.2.2",
"pokersolver": "^2.1.4",
-24
View File
@@ -1,5 +1,4 @@
const tf = require('@tensorflow/tfjs-node');
const nsfw = require('nsfwjs');
const faceDetection = require('@tensorflow-models/face-detection');
const faceModel = faceDetection.SupportedModels.MediaPipeFaceDetector;
const path = require('path');
@@ -9,18 +8,11 @@ module.exports = class Tensorflow {
constructor(client) {
Object.defineProperty(this, 'client', { value: client });
this.nsfwjs = null;
this.faceDetector = null;
this.styleModel = null;
this.transformerModel = null;
}
async loadNSFWJS() {
const nsfwjs = await nsfw.load('MobileNetV2');
this.nsfwjs = nsfwjs;
return this.nsfwjs;
}
async loadFaceDetector() {
const faceDetector = await faceDetection.createDetector(faceModel, { runtime: 'tfjs', maxFaces: 10 });
this.faceDetector = faceDetector;
@@ -55,22 +47,6 @@ module.exports = class Tensorflow {
return faces;
}
async isImageNSFW(image, bool = true) {
const img = await tf.node.decodeImage(image, 3);
const predictions = await this.nsfwjs.classify(img);
img.dispose();
if (bool) {
const results = [];
results.push(predictions[0]);
for (const result of predictions) {
if (result.className === predictions[0].className) continue;
if (result.probability >= predictions[0].probability - 0.1) results.push(result);
}
return results.some(result => result.className !== 'Drawing' && result.className !== 'Neutral');
}
return predictions;
}
async stylizeImage(image, styleImg) {
const imageTensor = await tf.node.decodeImage(image, 3);
const [originalHeight, originalWidth] = imageTensor.shape.slice(0, 2);