mirror of
https://github.com/arthur-pbty/xiao.git
synced 2026-06-03 23:36:43 +02:00
Remove NSFWJS
This commit is contained in:
@@ -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)
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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.",
|
||||
|
||||
@@ -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')}
|
||||
`);
|
||||
}
|
||||
};
|
||||
@@ -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?');
|
||||
|
||||
@@ -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
@@ -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",
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user