generated from ArcherGu/fast-vite-nestjs-electron
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[update] support SauceNAO & gif converter.
- Loading branch information
1 parent
85a3af5
commit 46f654f
Showing
29 changed files
with
833 additions
and
86 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,7 +1,9 @@ | ||
export interface IllustTodayDto { | ||
id?: number | ||
type: string | ||
base: string | ||
target: string | ||
tags?: string[] | ||
char?: string | ||
source?: string | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
14 changes: 14 additions & 0 deletions
14
src/main/known-duplicate/entities/pixiv-twitter.entities.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
import { Column, Entity, Index, PrimaryGeneratedColumn } from 'typeorm' | ||
|
||
@Entity() | ||
@Index(['pixiv_id', 'twitter_status_id'], { unique: true }) | ||
export class PixivTwitter { | ||
@PrimaryGeneratedColumn({ type: 'int' }) | ||
id: number | ||
|
||
@Column({ type: 'varchar', nullable: false }) | ||
pixiv_id: string | ||
|
||
@Column({ type: 'varchar', nullable: false }) | ||
twitter_status_id: string | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
import { Controller } from '@nestjs/common' | ||
import { IpcHandle } from '@doubleshot/nest-electron' | ||
import { Payload } from '@nestjs/microservices' | ||
import { KnownDuplicateService } from './known-duplicate.service' | ||
|
||
@Controller() | ||
export class KnownDuplicateController { | ||
constructor(private readonly knownDuplicateService: KnownDuplicateService) {} | ||
|
||
@IpcHandle('api:GET/known-duplicate/pixiv') | ||
getDuplicateByPixivId(@Payload() [{ pixiv_id }]: [{ pixiv_id: string }]) { | ||
return this.knownDuplicateService.getDuplicateByPixivId(pixiv_id) | ||
} | ||
|
||
@IpcHandle('api:GET/known-duplicate/twitter') | ||
getDuplicateByTwitterStatusId(@Payload() [{ twitter_status_id }]: [{ twitter_status_id: string }]) { | ||
return this.knownDuplicateService.getDuplicateByTwitterStatusId(twitter_status_id) | ||
} | ||
|
||
@IpcHandle('api:POST/known-duplicate/twitter') | ||
addDuplicate(@Payload() [{ pixiv_id, twitter_status_id }]: [{ pixiv_id: string; twitter_status_id: string }]) { | ||
return this.knownDuplicateService.addDuplicate(pixiv_id, twitter_status_id) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
import { Module } from '@nestjs/common' | ||
import { TypeOrmModule } from '@nestjs/typeorm' | ||
import { PixivTwitter } from './entities/pixiv-twitter.entities' | ||
import { KnownDuplicateService } from './known-duplicate.service' | ||
import { KnownDuplicateController } from './known-duplicate.controller' | ||
|
||
@Module({ | ||
imports: [ | ||
TypeOrmModule.forFeature([ | ||
PixivTwitter, | ||
]), | ||
], | ||
providers: [KnownDuplicateService, PixivTwitter], | ||
controllers: [KnownDuplicateController], | ||
}) | ||
export class KnownDuplicateModule {} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
import { Injectable } from '@nestjs/common' | ||
import { InjectRepository } from '@nestjs/typeorm' | ||
import { Repository } from 'typeorm' | ||
import { PixivTwitter } from './entities/pixiv-twitter.entities' | ||
|
||
@Injectable() | ||
export class KnownDuplicateService { | ||
constructor( | ||
@InjectRepository(PixivTwitter) | ||
private readonly pixivTwitterRepository: Repository<PixivTwitter>, | ||
) {} | ||
|
||
async getDuplicateByPixivId(pixiv_id: string) { | ||
const result = await this.pixivTwitterRepository.findOneBy({ pixiv_id }) | ||
if (result) | ||
return { target: result.twitter_status_id } | ||
} | ||
|
||
async getDuplicateByTwitterStatusId(twitter_status_id: string) { | ||
const result = await this.pixivTwitterRepository.findOneBy({ twitter_status_id }) | ||
if (result) | ||
return { target: result.pixiv_id } | ||
} | ||
|
||
async addDuplicate(pixiv_id: string, twitter_status_id: string) { | ||
if (await this.pixivTwitterRepository.findOneBy({ twitter_status_id })) | ||
return | ||
const newDuplicate = this.pixivTwitterRepository.create({ pixiv_id, twitter_status_id }) | ||
await this.pixivTwitterRepository.save(newDuplicate) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,141 @@ | ||
import fs from 'node:fs' | ||
import path from 'node:path' | ||
import type { Readable } from 'node:stream' | ||
import type { Buffer } from 'node:buffer' | ||
import sagiri from 'sagiri' | ||
import type { Options, SagiriResult } from 'sagiri' | ||
import { app } from 'electron' | ||
import { ConfigDB } from './DBService' | ||
|
||
type File = string | Buffer | Readable | ||
let client: (file: File, optionOverrides?: Options) => Promise<SagiriResult[]> = null | ||
const sleep_func = (ms: number) => new Promise(resolve => setTimeout(resolve, ms)) | ||
const RESULT_ROOT = path.join(app.getPath('userData'), 'sagiri_result') | ||
const GLOBAL_SIMILARITY_THRESHOLD = 75 | ||
|
||
class ProcessCore { | ||
static pixivFilter(json_obj: SagiriResult[]) { | ||
for (const result of json_obj) { | ||
if (result.similarity > GLOBAL_SIMILARITY_THRESHOLD && result.site === 'Pixiv') | ||
return new URL(result.url).searchParams.get('illust_id') ?? result.url.split('/')[result.url.split('/').length - 1] | ||
|
||
if (result.similarity > GLOBAL_SIMILARITY_THRESHOLD && result.raw?.data?.source?.startsWith('https://i.pximg.net')) | ||
return result.raw?.data?.source?.split('/')[result.raw?.data?.source?.split('/').length - 1] | ||
|
||
if (result.similarity > GLOBAL_SIMILARITY_THRESHOLD && result.raw?.data?.source?.startsWith('https://www.pixiv.net/artworks')) | ||
return result.raw?.data?.source?.split('/')[result.raw?.data?.source?.split('/').length - 1] | ||
} | ||
} | ||
|
||
static twiiterAllFilter(json_obj: SagiriResult[]) { | ||
for (const result of json_obj) { | ||
if (result.similarity > GLOBAL_SIMILARITY_THRESHOLD && result.site === 'Twitter') | ||
return result.url | ||
|
||
if (result.similarity > GLOBAL_SIMILARITY_THRESHOLD && result.raw?.data?.source?.startsWith('https://twitter.com')) | ||
return result.raw?.data?.source.split(' ')[0] | ||
} | ||
} | ||
|
||
static twiiterWithoutPixivFilter(json_obj: SagiriResult[]) { | ||
for (const result of json_obj) { | ||
if (result.similarity > GLOBAL_SIMILARITY_THRESHOLD && result.site === 'Pixiv') | ||
return | ||
|
||
if (result.similarity > GLOBAL_SIMILARITY_THRESHOLD && result.raw?.data?.source?.startsWith('https://i.pximg.net')) | ||
return | ||
|
||
if (result.similarity > GLOBAL_SIMILARITY_THRESHOLD && result.raw?.data?.source?.startsWith('https://www.pixiv.net/artworks')) | ||
return | ||
} | ||
return this.twiiterAllFilter(json_obj) | ||
} | ||
} | ||
|
||
export class SS { | ||
static async init() { | ||
if (!fs.existsSync(RESULT_ROOT)) | ||
fs.mkdirSync(RESULT_ROOT) | ||
const token = ConfigDB.getByKey('sauceNAOToken') | ||
if (token) | ||
client = sagiri(token) | ||
} | ||
|
||
static async runBatchAndDump(dir: string) { | ||
if (!client) | ||
throw new Error('SauceNAO client not initialized') | ||
const files = fs.readdirSync(dir).filter(file => ['.png', '.jpg', '.jpeg'].includes(path.extname(file).toLowerCase())) | ||
|
||
for (const file of files) { | ||
const prefix = path.basename(file, path.extname(file)) | ||
if (fs.existsSync(path.join(RESULT_ROOT, `${prefix}.json`))) | ||
continue | ||
const fileSize = fs.statSync(path.join(dir, file)).size | ||
if (fileSize > 20 * 1024 * 1024) | ||
continue | ||
const process = async () => { | ||
try { | ||
const result = await client(path.join(dir, file)) | ||
fs.writeFileSync(path.join(RESULT_ROOT, `${prefix}.json`), JSON.stringify(result)) | ||
await sleep_func(3000) | ||
} | ||
catch (err) { | ||
if (err.statusCode !== 413) { | ||
await sleep_func(10000) | ||
await process() | ||
} | ||
} | ||
} | ||
await process() | ||
} | ||
} | ||
|
||
static async runAndProcess(filePath: string) { | ||
if (!client) | ||
throw new Error('SauceNAO client not initialized') | ||
|
||
if (!['.png', '.jpg', '.jpeg'].includes(path.extname(filePath).toLowerCase())) | ||
return { error: 'Invalid file type' } | ||
|
||
const prefix = path.basename(filePath, path.extname(filePath)) | ||
if (fs.existsSync(path.join(RESULT_ROOT, `${prefix}.json`))) | ||
return { error: 'Result already exists' } | ||
|
||
const fileSize = fs.statSync(filePath).size | ||
if (fileSize > 20 * 1024 * 1024) | ||
return { error: 'File size too large' } | ||
|
||
let retry = 0 | ||
|
||
const process = async () => { | ||
try { | ||
const result = await client(filePath) | ||
return { | ||
pixiv: ProcessCore.pixivFilter(result), | ||
twitter: ProcessCore.twiiterAllFilter(result), | ||
} | ||
} | ||
catch (err) { | ||
if (retry++ < 3) { | ||
await sleep_func(10000) | ||
return await process() | ||
} | ||
else { | ||
return { error: `Failed to process image ${err}` } | ||
} | ||
} | ||
} | ||
return await process() | ||
} | ||
|
||
static parseJsonResult(filePath: string) { | ||
const json = fs.readFileSync(filePath, 'utf-8') | ||
const result: SagiriResult[] = JSON.parse(json) | ||
return { | ||
pixiv: ProcessCore.pixivFilter(result), | ||
twitter: ProcessCore.twiiterAllFilter(result), | ||
} | ||
} | ||
} | ||
|
||
SS.init() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.