Compare commits
13 Commits
develop
...
minify-bun
| Author | SHA1 | Date |
|---|---|---|
|
|
1288076f31 | |
|
|
4f67d671cc | |
|
|
b53f3a5bd5 | |
|
|
bbd3a176a2 | |
|
|
5871037b31 | |
|
|
6baa5463dc | |
|
|
8bba88670b | |
|
|
e44f993b6b | |
|
|
7ed582e3b7 | |
|
|
ab5c38875d | |
|
|
01b0c764a5 | |
|
|
c770a1746d | |
|
|
83cdef298b |
|
|
@ -40,6 +40,3 @@ updates:
|
||||||
typescript-eslint:
|
typescript-eslint:
|
||||||
patterns:
|
patterns:
|
||||||
- "@typescript-eslint/*"
|
- "@typescript-eslint/*"
|
||||||
tensorflow:
|
|
||||||
patterns:
|
|
||||||
- "@tensorflow/*"
|
|
||||||
|
|
|
||||||
|
|
@ -83,9 +83,6 @@
|
||||||
"typescript": "5.9.3",
|
"typescript": "5.9.3",
|
||||||
"start-server-and-test": "2.1.3"
|
"start-server-and-test": "2.1.3"
|
||||||
},
|
},
|
||||||
"optionalDependencies": {
|
|
||||||
"@tensorflow/tfjs-core": "4.22.0"
|
|
||||||
},
|
|
||||||
"pnpm": {
|
"pnpm": {
|
||||||
"overrides": {
|
"overrides": {
|
||||||
"@aiscript-dev/aiscript-languageserver": "-"
|
"@aiscript-dev/aiscript-languageserver": "-"
|
||||||
|
|
|
||||||
|
|
@ -42,8 +42,8 @@ const options = {
|
||||||
target: 'node22',
|
target: 'node22',
|
||||||
platform: 'node',
|
platform: 'node',
|
||||||
format: 'esm',
|
format: 'esm',
|
||||||
sourcemap: 'linked',
|
sourcemap: false,
|
||||||
packages: 'external',
|
packages: 'bundle',
|
||||||
banner: {
|
banner: {
|
||||||
js: 'import { createRequire as topLevelCreateRequire } from "module";' +
|
js: 'import { createRequire as topLevelCreateRequire } from "module";' +
|
||||||
'import ___url___ from "url";' +
|
'import ___url___ from "url";' +
|
||||||
|
|
@ -76,25 +76,26 @@ const options = {
|
||||||
keepClassNames: true,
|
keepClassNames: true,
|
||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
externalIpaddrPlugin,
|
//externalIpaddrPlugin,
|
||||||
|
],
|
||||||
|
external: [
|
||||||
|
'slacc-*',
|
||||||
|
'class-transformer',
|
||||||
|
'class-validator',
|
||||||
|
'@sentry/*',
|
||||||
|
'@nestjs/websockets/socket-module',
|
||||||
|
'@nestjs/microservices/microservices-module',
|
||||||
|
'@nestjs/microservices',
|
||||||
|
'@napi-rs/canvas-win32-x64-msvc',
|
||||||
|
'mock-aws-s3',
|
||||||
|
'aws-sdk',
|
||||||
|
'nock',
|
||||||
|
'sharp',
|
||||||
|
're2',
|
||||||
|
'@napi-rs/canvas',
|
||||||
|
'oauth2orize',
|
||||||
|
'oauth2orize-pkce',
|
||||||
],
|
],
|
||||||
// external: [
|
|
||||||
// 'slacc-*',
|
|
||||||
// 'class-transformer',
|
|
||||||
// 'class-validator',
|
|
||||||
// '@sentry/*',
|
|
||||||
// '@nestjs/websockets/socket-module',
|
|
||||||
// '@nestjs/microservices/microservices-module',
|
|
||||||
// '@nestjs/microservices',
|
|
||||||
// '@napi-rs/canvas-win32-x64-msvc',
|
|
||||||
// 'mock-aws-s3',
|
|
||||||
// 'aws-sdk',
|
|
||||||
// 'nock',
|
|
||||||
// 'sharp',
|
|
||||||
// 'jsdom',
|
|
||||||
// 're2',
|
|
||||||
// '@napi-rs/canvas',
|
|
||||||
// ],
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const args = process.argv.slice(2).map(arg => arg.toLowerCase());
|
const args = process.argv.slice(2).map(arg => arg.toLowerCase());
|
||||||
|
|
|
||||||
Binary file not shown.
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
|
@ -52,8 +52,6 @@
|
||||||
"@swc/core-win32-arm64-msvc": "1.15.7",
|
"@swc/core-win32-arm64-msvc": "1.15.7",
|
||||||
"@swc/core-win32-ia32-msvc": "1.15.7",
|
"@swc/core-win32-ia32-msvc": "1.15.7",
|
||||||
"@swc/core-win32-x64-msvc": "1.15.7",
|
"@swc/core-win32-x64-msvc": "1.15.7",
|
||||||
"@tensorflow/tfjs": "4.22.0",
|
|
||||||
"@tensorflow/tfjs-node": "4.22.0",
|
|
||||||
"bufferutil": "4.1.0",
|
"bufferutil": "4.1.0",
|
||||||
"slacc-android-arm-eabi": "0.0.10",
|
"slacc-android-arm-eabi": "0.0.10",
|
||||||
"slacc-android-arm64": "0.0.10",
|
"slacc-android-arm64": "0.0.10",
|
||||||
|
|
@ -141,7 +139,6 @@
|
||||||
"node-fetch": "3.3.2",
|
"node-fetch": "3.3.2",
|
||||||
"node-html-parser": "7.0.1",
|
"node-html-parser": "7.0.1",
|
||||||
"nodemailer": "7.0.12",
|
"nodemailer": "7.0.12",
|
||||||
"nsfwjs": "4.2.0",
|
|
||||||
"oauth2orize": "1.12.0",
|
"oauth2orize": "1.12.0",
|
||||||
"oauth2orize-pkce": "0.1.2",
|
"oauth2orize-pkce": "0.1.2",
|
||||||
"os-utils": "0.0.14",
|
"os-utils": "0.0.14",
|
||||||
|
|
|
||||||
|
|
@ -3,88 +3,17 @@
|
||||||
* SPDX-License-Identifier: AGPL-3.0-only
|
* SPDX-License-Identifier: AGPL-3.0-only
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import * as fs from 'node:fs';
|
|
||||||
import { fileURLToPath } from 'node:url';
|
|
||||||
import { dirname } from 'node:path';
|
|
||||||
import { Injectable } from '@nestjs/common';
|
import { Injectable } from '@nestjs/common';
|
||||||
import { Mutex } from 'async-mutex';
|
|
||||||
import fetch from 'node-fetch';
|
|
||||||
import { bindThis } from '@/decorators.js';
|
import { bindThis } from '@/decorators.js';
|
||||||
import type { NSFWJS, PredictionType } from 'nsfwjs';
|
|
||||||
|
|
||||||
const _filename = fileURLToPath(import.meta.url);
|
|
||||||
const _dirname = dirname(_filename);
|
|
||||||
|
|
||||||
const REQUIRED_CPU_FLAGS_X64 = ['avx2', 'fma'];
|
|
||||||
let isSupportedCpu: undefined | boolean = undefined;
|
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class AiService {
|
export class AiService {
|
||||||
private model: NSFWJS;
|
|
||||||
private modelLoadMutex: Mutex = new Mutex();
|
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
) {
|
) {
|
||||||
}
|
}
|
||||||
|
|
||||||
@bindThis
|
@bindThis
|
||||||
public async detectSensitive(source: string | Buffer): Promise<PredictionType[] | null> {
|
public async detectSensitive(source: string | Buffer): Promise<null> {
|
||||||
try {
|
|
||||||
if (isSupportedCpu === undefined) {
|
|
||||||
isSupportedCpu = await this.computeIsSupportedCpu();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!isSupportedCpu) {
|
|
||||||
console.error('This CPU cannot use TensorFlow.');
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
const tf = await import('@tensorflow/tfjs-node');
|
|
||||||
tf.env().global.fetch = fetch;
|
|
||||||
|
|
||||||
if (this.model == null) {
|
|
||||||
const nsfw = await import('nsfwjs');
|
|
||||||
await this.modelLoadMutex.runExclusive(async () => {
|
|
||||||
if (this.model == null) {
|
|
||||||
this.model = await nsfw.load(`file://${_dirname}/../../nsfw-model/`, { size: 299 });
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
const buffer = source instanceof Buffer ? source : await fs.promises.readFile(source);
|
|
||||||
const image = await tf.node.decodeImage(buffer, 3) as any;
|
|
||||||
try {
|
|
||||||
const predictions = await this.model.classify(image);
|
|
||||||
return predictions;
|
|
||||||
} finally {
|
|
||||||
image.dispose();
|
|
||||||
}
|
|
||||||
} catch (err) {
|
|
||||||
console.error(err);
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private async computeIsSupportedCpu(): Promise<boolean> {
|
|
||||||
switch (process.arch) {
|
|
||||||
case 'x64': {
|
|
||||||
const cpuFlags = await this.getCpuFlags();
|
|
||||||
return REQUIRED_CPU_FLAGS_X64.every(required => cpuFlags.includes(required));
|
|
||||||
}
|
|
||||||
case 'arm64': {
|
|
||||||
// As far as I know, no required CPU flags for ARM64.
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
default: {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@bindThis
|
|
||||||
private async getCpuFlags(): Promise<string[]> {
|
|
||||||
const si = await import('systeminformation');
|
|
||||||
const str = await si.cpuFlags();
|
|
||||||
return str.split(/\s+/);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
||||||
519
pnpm-lock.yaml
519
pnpm-lock.yaml
File diff suppressed because it is too large
Load Diff
|
|
@ -17,7 +17,6 @@ onlyBuiltDependencies:
|
||||||
- '@sentry/profiling-node'
|
- '@sentry/profiling-node'
|
||||||
- '@sentry-internal/node-cpu-profiler'
|
- '@sentry-internal/node-cpu-profiler'
|
||||||
- '@swc/core'
|
- '@swc/core'
|
||||||
- '@tensorflow/tfjs-node'
|
|
||||||
- bufferutil
|
- bufferutil
|
||||||
- canvas
|
- canvas
|
||||||
- core-js
|
- core-js
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue