Skip to content

Commit

Permalink
Merge pull request #9 from GNUWeeb/experimental
Browse files Browse the repository at this point in the history
Experimental
  • Loading branch information
fadhil-riyanto authored Jan 15, 2025
2 parents fe8413c + e9e580b commit a9a6307
Show file tree
Hide file tree
Showing 5 changed files with 197 additions and 60 deletions.
143 changes: 85 additions & 58 deletions src/commands/kang.ts
Original file line number Diff line number Diff line change
@@ -1,22 +1,23 @@
import { createCommand } from '../utils/command';
import {
invalidInput,
kangStickerRequestedNotFound
} from '../helper/errors';
import { stickerpackStateModel } from '../models/stickerpackState';
import { CommandContext, Context, GrammyError } from 'grammy';
import { InputFile, InputSticker, Message } from 'grammy/types';
import { BotHelpers, IStickerpackData, IEmojiSanitizeResult, IStickerpackDataReversed } from '../helper/strings';
import { apiHelper } from '../helper/apiHelper';
import { downloadFileToTemp } from '../helper/io';
import sharp from 'sharp';
import { ReplyParameters } from 'grammy/types';
import { StickerRequestedNotFound } from '../error/stickerRequestedNotFound';
import { EmojiInputInvalid } from '../error/EmojiInputInvalid';
import { IndexPackInvalid } from '../error/IndexPackInvalid';
import { KangInputInvalid } from '../error/KangInputInvalid';
import { StickerTooMuchSynteticTrue } from '../error/stickerTooMuch';
import { logger } from '../utils/logger';
import { dbHelper } from '../helper/dbHelper';
import axios from "axios";
import * as fs from "fs";
import { FileStorage } from '../helper/io';

interface tgCallErrcode {
code: number;
Expand Down Expand Up @@ -69,45 +70,6 @@ class stickerPackManagement {
return generatedName.stickerName
}

private async appendNewStickerSetToUID(user_id: number, newStickersetName: string) {
let old = await stickerpackStateModel.findOne({
user_id: user_id
});

let newAppendSticker: string[] = old?.stickersetname!;
newAppendSticker.push(newStickersetName!);

await stickerpackStateModel.updateOne(
{
user_id: user_id
},
{
stickersetname: newAppendSticker
}
)
}

private async removeStickerSetFromUID(user_id: number, stickersetName: string) {
let old = await stickerpackStateModel.findOne({
user_id: user_id
});

let repackArr: string[] = old?.stickersetname!;
const index = repackArr.indexOf(stickersetName);
if (index > -1) { // only splice array when item is found
repackArr.splice(index, 1); // 2nd parameter means remove one item only
}

await stickerpackStateModel.updateOne(
{
user_id: user_id
},
{
stickersetname: repackArr
}
)
}

private async addStickerToPack(stickerFileId: string):
Promise<tgCallErrcode> {
let input: InputSticker = {
Expand Down Expand Up @@ -320,7 +282,7 @@ class stickerPackManagement {
} else {
this.data.synthetic_req_stickerpack = true;
}


await this.modelCreateRecordFirstTime(newlyGeneratedData)
/**
Expand Down Expand Up @@ -395,7 +357,7 @@ class stickerPackManagement {
/**
* create completion
*/
await this.appendNewStickerSetToUID(
await dbHelper.appendNewStickerSetToUID(
this.ctx.message?.from.id!,
this.data.stickerName!
);
Expand All @@ -409,14 +371,14 @@ class stickerPackManagement {
/**
* malformed data, need to delete
*/
await this.removeStickerSetFromUID(
await dbHelper.removeStickerSetFromUID(
this.ctx.message?.from.id!,
this.data.stickerName!
)
} else if (tgServerSideFoundSticker == false && localFoundSticker == false) {
ret = await this.createNewStickerpack(stickerFileId);
if (ret.code == 0) {
await this.appendNewStickerSetToUID(
await dbHelper.appendNewStickerSetToUID(
this.ctx.message?.from.id!,
this.data.stickerName!
);
Expand Down Expand Up @@ -507,22 +469,14 @@ const processImage = async (fileName: string): Promise<string> => {
return outImage;
};


const kangFromImage = async (
ctx: CommandContext<Context>,
stickerManagementCtx: stickerPackManagement
): Promise<void> => {
/* setup reply id */
const _kangFromImageLocals = async (ctx: CommandContext<Context>,
stickerManagementCtx: stickerPackManagement, path: string): Promise<void> =>
{
let replyparam: ReplyParameters = {
message_id: ctx.message?.message_id!,
};

const largestphoto = ctx.message?.reply_to_message?.photo?.pop();
const file: any = await ctx.api.getFile(largestphoto?.file_id!);

const tempDataPath = await file.download();

let resizedImage = await processImage(tempDataPath);
let resizedImage = await processImage(path);

let sentSticker: Message = await ctx.api.sendSticker(
ctx.message?.chat.id!,
Expand All @@ -540,8 +494,77 @@ const kangFromImage = async (
parse_mode: 'HTML',
}
);
}


const kangFromImage = async (
ctx: CommandContext<Context>,
stickerManagementCtx: stickerPackManagement
): Promise<void> => {
/* setup reply id */


const largestphoto = ctx.message?.reply_to_message?.photo?.pop();
const file: any = await ctx.api.getFile(largestphoto?.file_id!);

const tempDataPath = await file.download();
await _kangFromImageLocals(ctx, stickerManagementCtx, tempDataPath)

};

const kangFromText = async (ctx: CommandContext<Context>,
stickerManagementCtx: stickerPackManagement
): Promise<void> => {

let avatarUrl: string | null = null;

const avatarArr = await ctx.api.getUserProfilePhotos(ctx.message?.reply_to_message?.from?.id!)

if (avatarArr.photos.length != 0) {
const avatarFile: any = await ctx.api.getFile(avatarArr.photos[0].pop()?.file_id!)
avatarUrl = avatarFile.getUrl()
} else {
avatarUrl = null
}

const json = {
"type": "quote",
"format": "png",
"backgroundColor": "#FFFFFF",
"width": 512,
"height": 768,
"scale": 2,
"messages": [
{
"entities": [],
"avatar": true,
"from": {
"id": 1,
"name": BotHelpers.normalizeName(ctx),
"photo": {
"url": avatarUrl
}
},
"text": ctx.message?.reply_to_message?.text!,
"replyMessage": {}
}
]
};
const response = axios.post('https://bot.lyo.su/quote/generate', json, {
headers: { 'Content-Type': 'application/json' }
}).then(async (res) => {
const buffer = Buffer.from(res.data.result.image, 'base64')

let bufCtx = new FileStorage("/tmp")
let path: string = await bufCtx.storeFileRand(buffer)

await _kangFromImageLocals(ctx, stickerManagementCtx, path)
await bufCtx.removeFile(path)


})
}

const kangCommand = createCommand(
{
name: 'kang',
Expand Down Expand Up @@ -573,6 +596,10 @@ const kangCommand = createCommand(
ctx.message?.reply_to_message?.sticker == undefined
) {
await kangFromImage(ctx, stickerManagementCtx);
} else if (
ctx.message?.reply_to_message?.text != undefined
) {
await kangFromText(ctx, stickerManagementCtx);
} else {
await invalidInput(ctx);
}
Expand Down
15 changes: 14 additions & 1 deletion src/commands/unkang.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,15 @@ import { invalidInput } from '../helper/errors';
import { stickerpackStateModel } from '../models/stickerpackState';
import { CommandContext, Context } from 'grammy';
import { ReplyParameters } from 'grammy/types';
import { dbHelper } from '../helper/dbHelper';

const sanitizeIsEmpty = async (ctx: CommandContext<Context>, setName: string): Promise<void> => {
let res = await ctx.api.getStickerSet(setName);
console.log(res)
if (res.stickers.length == 0) {
await dbHelper.removeStickerSetFromUID(ctx.message?.from.id!, setName);
}
}

const removeStickerFromSet = async (ctx: CommandContext<Context>): Promise<void> => {
let replyparam: ReplyParameters = {
Expand All @@ -14,7 +23,7 @@ const removeStickerFromSet = async (ctx: CommandContext<Context>): Promise<void>
user_id: ctx.message?.from.id!,
});

if (!StickerpackStateDoc) {
if (StickerpackStateDoc?.stickersetname.length == 0) {
await ctx.reply("You don't have any active stickerpack!", {
reply_parameters: replyparam,
});
Expand All @@ -36,6 +45,10 @@ const removeStickerFromSet = async (ctx: CommandContext<Context>): Promise<void>
await ctx.reply('Sticker successfully removed from the pack!', {
reply_parameters: replyparam,
});

await sanitizeIsEmpty(ctx, ctx.message?.reply_to_message?.sticker?.set_name!);


} catch (error) {
await ctx.reply('Failed to remove sticker from pack. Make sure you own this stickerpack!', {
reply_parameters: replyparam,
Expand Down
43 changes: 43 additions & 0 deletions src/helper/dbHelper.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import { stickerpackStateModel } from "../models/stickerpackState";

export class dbHelper {
public static async appendNewStickerSetToUID(user_id: number, newStickersetName: string) {
let old = await stickerpackStateModel.findOne({
user_id: user_id
});

let newAppendSticker: string[] = old?.stickersetname!;
newAppendSticker.push(newStickersetName!);

await stickerpackStateModel.updateOne(
{
user_id: user_id
},
{
stickersetname: newAppendSticker
}
)
}


public static async removeStickerSetFromUID(user_id: number, stickersetName: string) {
let old = await stickerpackStateModel.findOne({
user_id: user_id
});

let repackArr: string[] = old?.stickersetname!;
const index = repackArr.indexOf(stickersetName);
if (index > -1) { // only splice array when item is found
repackArr.splice(index, 1); // 2nd parameter means remove one item only
}

await stickerpackStateModel.updateOne(
{
user_id: user_id
},
{
stickersetname: repackArr
}
)
}
}
46 changes: 46 additions & 0 deletions src/helper/io.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import https from 'https';
import fs from 'fs';
import path from 'path';
import os from 'os';
import { BotHelpers } from './strings';

export const downloadFileToTemp = async (url: string, filename?: string): Promise<string> => {
return new Promise((resolve, reject) => {
Expand Down Expand Up @@ -32,3 +33,48 @@ export const downloadFileToTemp = async (url: string, filename?: string): Promis
});
});
};


export class FileStorage {
private storageDir: string;

constructor(storageDir: string) {
this.storageDir = storageDir;

// Ensure the storage directory exists
if (!fs.existsSync(this.storageDir)) {
fs.mkdirSync(this.storageDir, { recursive: true });
}
}

/**
* Store a file from a Buffer.
* @param fileName The name of the file to store.
* @param buffer The Buffer containing file data.
*/
public async storeFile(fileName: string, buffer: Buffer): Promise<void> {
const filePath = path.join(this.storageDir, fileName);
return fs.promises.writeFile(filePath, buffer);
}

public async storeFileRand(buffer: Buffer)
{
let fileName: string = BotHelpers.genRandomFileName("result.png");
await this.storeFile(fileName, buffer)

const filePath = path.join(this.storageDir, fileName)
return filePath;
}

/**
* Remove a stored file.
* @param fileName The name of the file to remove.
*/
public async removeFile(fileName: string): Promise<void> {
if (fs.existsSync(fileName)) {
return fs.promises.unlink(fileName);
} else {
throw new Error(`File "${fileName}" does not exist.`);
}
}
}
10 changes: 9 additions & 1 deletion src/helper/strings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@ export class BotHelpers extends String {
split.forEach((cmd: string, i: number) => {
if (i != 0) {
rawArr.push(cmd)
}
}
})

if (rawArr.length == 0) {
Expand All @@ -147,4 +147,12 @@ export class BotHelpers extends String {
return rawArr.join(' ')
}
}

public static normalizeName(ctx: CommandContext<Context>): string {
if (ctx.message?.reply_to_message?.from?.last_name == undefined) {
return ctx.message?.reply_to_message?.from?.first_name!;
}else {
return `${ctx.message?.reply_to_message?.from?.first_name} ${ctx.message?.reply_to_message?.from?.last_name}`
}
}
}

0 comments on commit a9a6307

Please sign in to comment.