Compare commits
No commits in common. "5a7ba81f462401a1282778e5800f111b1cd65be2" and "4d69b87b97f740300adf42503d476b800236f0a0" have entirely different histories.
5a7ba81f46
...
4d69b87b97
23
bot/mod.ts
23
bot/mod.ts
@ -1,9 +1,8 @@
|
|||||||
import { Grammy, GrammyAutoQuote, GrammyFiles, GrammyParseMode, Log } from "../deps.ts";
|
import { Grammy, GrammyAutoQuote, GrammyParseMode, Log } from "../deps.ts";
|
||||||
import { formatUserChat } from "../utils.ts";
|
import { formatUserChat } from "../utils.ts";
|
||||||
import { session, SessionFlavor } from "./session.ts";
|
import { session, SessionFlavor } from "./session.ts";
|
||||||
import { queueCommand } from "./queueCommand.ts";
|
import { queueCommand } from "./queueCommand.ts";
|
||||||
import { txt2imgCommand, txt2imgQuestion } from "./txt2imgCommand.ts";
|
import { txt2imgCommand, txt2imgQuestion } from "./txt2imgCommand.ts";
|
||||||
import { pnginfoCommand, pnginfoQuestion } from "./pnginfoCommand.ts";
|
|
||||||
|
|
||||||
export const logger = () => Log.getLogger();
|
export const logger = () => Log.getLogger();
|
||||||
|
|
||||||
@ -13,9 +12,7 @@ type WithRetryApi<T extends Grammy.RawApi> = {
|
|||||||
: T[M];
|
: T[M];
|
||||||
};
|
};
|
||||||
|
|
||||||
export type Context =
|
export type Context = GrammyParseMode.ParseModeFlavor<Grammy.Context> & SessionFlavor;
|
||||||
& GrammyFiles.FileFlavor<GrammyParseMode.ParseModeFlavor<Grammy.Context>>
|
|
||||||
& SessionFlavor;
|
|
||||||
export const bot = new Grammy.Bot<Context, Grammy.Api<WithRetryApi<Grammy.RawApi>>>(
|
export const bot = new Grammy.Bot<Context, Grammy.Api<WithRetryApi<Grammy.RawApi>>>(
|
||||||
Deno.env.get("TG_BOT_TOKEN") ?? "",
|
Deno.env.get("TG_BOT_TOKEN") ?? "",
|
||||||
);
|
);
|
||||||
@ -23,7 +20,9 @@ bot.use(GrammyAutoQuote.autoQuote);
|
|||||||
bot.use(GrammyParseMode.hydrateReply);
|
bot.use(GrammyParseMode.hydrateReply);
|
||||||
bot.use(session);
|
bot.use(session);
|
||||||
|
|
||||||
bot.api.config.use(GrammyFiles.hydrateFiles(bot.token));
|
bot.catch((err) => {
|
||||||
|
logger().error(`Handling update from ${formatUserChat(err.ctx)} failed: ${err}`);
|
||||||
|
});
|
||||||
|
|
||||||
// Automatically retry bot requests if we get a "too many requests" or telegram internal error
|
// Automatically retry bot requests if we get a "too many requests" or telegram internal error
|
||||||
bot.api.config.use(async (prev, method, payload, signal) => {
|
bot.api.config.use(async (prev, method, payload, signal) => {
|
||||||
@ -40,19 +39,13 @@ bot.api.config.use(async (prev, method, payload, signal) => {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
logger().warning(
|
logger().warning(
|
||||||
`${method} (attempt ${attempt}) failed: ${result.error_code} ${result.description}`,
|
`Retrying ${method} after attempt ${attempt} failed with ${result.error_code} error`,
|
||||||
);
|
);
|
||||||
const retryAfterMs = (result.parameters?.retry_after ?? (attempt * 5)) * 1000;
|
const retryAfterMs = (result.parameters?.retry_after ?? (attempt * 5)) * 1000;
|
||||||
await new Promise((resolve) => setTimeout(resolve, retryAfterMs));
|
await new Promise((resolve) => setTimeout(resolve, retryAfterMs));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
bot.catch((err) => {
|
|
||||||
logger().error(
|
|
||||||
`Handling update from ${formatUserChat(err.ctx)} failed: ${err.name} ${err.message}`,
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
// if error happened, try to reply to the user with the error
|
// if error happened, try to reply to the user with the error
|
||||||
bot.use(async (ctx, next) => {
|
bot.use(async (ctx, next) => {
|
||||||
try {
|
try {
|
||||||
@ -75,7 +68,6 @@ bot.api.setMyDescription(
|
|||||||
);
|
);
|
||||||
bot.api.setMyCommands([
|
bot.api.setMyCommands([
|
||||||
{ command: "txt2img", description: "Generate an image" },
|
{ command: "txt2img", description: "Generate an image" },
|
||||||
{ command: "pnginfo", description: "Show generation parameters of an image" },
|
|
||||||
{ command: "queue", description: "Show the current queue" },
|
{ command: "queue", description: "Show the current queue" },
|
||||||
]);
|
]);
|
||||||
|
|
||||||
@ -84,9 +76,6 @@ bot.command("start", (ctx) => ctx.reply("Hello! Use the /txt2img command to gene
|
|||||||
bot.command("txt2img", txt2imgCommand);
|
bot.command("txt2img", txt2imgCommand);
|
||||||
bot.use(txt2imgQuestion.middleware());
|
bot.use(txt2imgQuestion.middleware());
|
||||||
|
|
||||||
bot.command("pnginfo", pnginfoCommand);
|
|
||||||
bot.use(pnginfoQuestion.middleware());
|
|
||||||
|
|
||||||
bot.command("queue", queueCommand);
|
bot.command("queue", queueCommand);
|
||||||
|
|
||||||
bot.command("pause", (ctx) => {
|
bot.command("pause", (ctx) => {
|
||||||
|
@ -1,51 +0,0 @@
|
|||||||
import { Grammy, GrammyParseMode, GrammyStatelessQ } from "../deps.ts";
|
|
||||||
import { fmt } from "../utils.ts";
|
|
||||||
|
|
||||||
import { getPngInfo, parsePngInfo } from "../sd.ts";
|
|
||||||
import { Context } from "./mod.ts";
|
|
||||||
|
|
||||||
export const pnginfoQuestion = new GrammyStatelessQ.StatelessQuestion<Context>(
|
|
||||||
"pnginfo",
|
|
||||||
async (ctx) => {
|
|
||||||
await pnginfo(ctx, false);
|
|
||||||
},
|
|
||||||
);
|
|
||||||
|
|
||||||
export async function pnginfoCommand(ctx: Grammy.CommandContext<Context>) {
|
|
||||||
await pnginfo(ctx, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
async function pnginfo(ctx: Context, includeRepliedTo: boolean): Promise<void> {
|
|
||||||
const document = ctx.message?.document ||
|
|
||||||
(includeRepliedTo ? ctx.message?.reply_to_message?.document : undefined);
|
|
||||||
|
|
||||||
if (document?.mime_type !== "image/png") {
|
|
||||||
await ctx.reply(
|
|
||||||
"Please send me a PNG file." +
|
|
||||||
pnginfoQuestion.messageSuffixMarkdown(),
|
|
||||||
{ reply_markup: { force_reply: true, selective: true }, parse_mode: "Markdown" },
|
|
||||||
);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const file = await ctx.api.getFile(document.file_id);
|
|
||||||
const buffer = await fetch(file.getUrl()).then((resp) => resp.arrayBuffer());
|
|
||||||
const params = parsePngInfo(getPngInfo(new Uint8Array(buffer)) ?? "");
|
|
||||||
|
|
||||||
const { bold } = GrammyParseMode;
|
|
||||||
|
|
||||||
const paramsText = fmt([
|
|
||||||
`${params.prompt}\n`,
|
|
||||||
params.negative_prompt ? fmt`${bold("Negative prompt:")} ${params.negative_prompt}\n` : "",
|
|
||||||
params.steps ? fmt`${bold("Steps:")} ${params.steps}, ` : "",
|
|
||||||
params.sampler_name ? fmt`${bold("Sampler:")} ${params.sampler_name}, ` : "",
|
|
||||||
params.cfg_scale ? fmt`${bold("CFG scale:")} ${params.cfg_scale}, ` : "",
|
|
||||||
params.seed ? fmt`${bold("Seed:")} ${params.seed}, ` : "",
|
|
||||||
params.width && params.height ? fmt`${bold("Size")}: ${params.width}x${params.height}` : "",
|
|
||||||
]);
|
|
||||||
|
|
||||||
await ctx.reply(paramsText.text, {
|
|
||||||
reply_to_message_id: ctx.message?.message_id,
|
|
||||||
entities: paramsText.entities,
|
|
||||||
});
|
|
||||||
}
|
|
@ -1,7 +1,7 @@
|
|||||||
import { Grammy, GrammyStatelessQ } from "../deps.ts";
|
import { Grammy, GrammyStatelessQ } from "../deps.ts";
|
||||||
import { formatUserChat } from "../utils.ts";
|
import { formatUserChat } from "../utils.ts";
|
||||||
import { jobStore } from "../db/jobStore.ts";
|
import { jobStore } from "../db/jobStore.ts";
|
||||||
import { getPngInfo, parsePngInfo, SdTxt2ImgRequest } from "../sd.ts";
|
import { parsePngInfo } from "../sd.ts";
|
||||||
import { Context, logger } from "./mod.ts";
|
import { Context, logger } from "./mod.ts";
|
||||||
|
|
||||||
export const txt2imgQuestion = new GrammyStatelessQ.StatelessQuestion<Context>(
|
export const txt2imgQuestion = new GrammyStatelessQ.StatelessQuestion<Context>(
|
||||||
@ -43,23 +43,8 @@ async function txt2img(ctx: Context, match: string, includeRepliedTo: boolean):
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let params: Partial<SdTxt2ImgRequest> = {};
|
let params = parsePngInfo(match);
|
||||||
|
|
||||||
const repliedToMsg = ctx.message.reply_to_message;
|
const repliedToMsg = ctx.message.reply_to_message;
|
||||||
|
|
||||||
if (includeRepliedTo && repliedToMsg?.document?.mime_type === "image/png") {
|
|
||||||
const file = await ctx.api.getFile(repliedToMsg.document.file_id);
|
|
||||||
const buffer = await fetch(file.getUrl()).then((resp) => resp.arrayBuffer());
|
|
||||||
const fileParams = parsePngInfo(getPngInfo(new Uint8Array(buffer)) ?? "");
|
|
||||||
params = {
|
|
||||||
...params,
|
|
||||||
...fileParams,
|
|
||||||
prompt: [params.prompt, fileParams.prompt].filter(Boolean).join("\n"),
|
|
||||||
negative_prompt: [params.negative_prompt, fileParams.negative_prompt]
|
|
||||||
.filter(Boolean).join("\n"),
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
const repliedToText = repliedToMsg?.text || repliedToMsg?.caption;
|
const repliedToText = repliedToMsg?.text || repliedToMsg?.caption;
|
||||||
if (includeRepliedTo && repliedToText) {
|
if (includeRepliedTo && repliedToText) {
|
||||||
// TODO: remove bot command from replied to text
|
// TODO: remove bot command from replied to text
|
||||||
@ -68,18 +53,8 @@ async function txt2img(ctx: Context, match: string, includeRepliedTo: boolean):
|
|||||||
...originalParams,
|
...originalParams,
|
||||||
...params,
|
...params,
|
||||||
prompt: [originalParams.prompt, params.prompt].filter(Boolean).join("\n"),
|
prompt: [originalParams.prompt, params.prompt].filter(Boolean).join("\n"),
|
||||||
negative_prompt: [originalParams.negative_prompt, params.negative_prompt]
|
|
||||||
.filter(Boolean).join("\n"),
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
const messageParams = parsePngInfo(match);
|
|
||||||
params = {
|
|
||||||
...params,
|
|
||||||
...messageParams,
|
|
||||||
prompt: [params.prompt, messageParams.prompt].filter(Boolean).join("\n"),
|
|
||||||
};
|
|
||||||
|
|
||||||
if (!params.prompt) {
|
if (!params.prompt) {
|
||||||
await ctx.reply(
|
await ctx.reply(
|
||||||
"Please tell me what you want to see." +
|
"Please tell me what you want to see." +
|
||||||
|
1
deps.ts
1
deps.ts
@ -12,7 +12,6 @@ export * as GrammyAutoQuote from "https://deno.land/x/grammy_autoquote@v1.1.2/mo
|
|||||||
export * as GrammyParseMode from "https://deno.land/x/grammy_parse_mode@1.7.1/mod.ts";
|
export * as GrammyParseMode from "https://deno.land/x/grammy_parse_mode@1.7.1/mod.ts";
|
||||||
export * as GrammyKvStorage from "https://deno.land/x/grammy_storages@v2.3.1/denokv/src/mod.ts";
|
export * as GrammyKvStorage from "https://deno.land/x/grammy_storages@v2.3.1/denokv/src/mod.ts";
|
||||||
export * as GrammyStatelessQ from "https://deno.land/x/grammy_stateless_question_alpha@v3.0.3/mod.ts";
|
export * as GrammyStatelessQ from "https://deno.land/x/grammy_stateless_question_alpha@v3.0.3/mod.ts";
|
||||||
export * as GrammyFiles from "https://deno.land/x/grammy_files@v1.0.4/mod.ts";
|
|
||||||
export * as FileType from "npm:file-type@18.5.0";
|
export * as FileType from "npm:file-type@18.5.0";
|
||||||
// @deno-types="./types/png-chunks-extract.d.ts"
|
// @deno-types="./types/png-chunks-extract.d.ts"
|
||||||
export * as PngChunksExtract from "npm:png-chunks-extract@1.0.0";
|
export * as PngChunksExtract from "npm:png-chunks-extract@1.0.0";
|
||||||
|
@ -1,83 +0,0 @@
|
|||||||
import {
|
|
||||||
assert,
|
|
||||||
assertEquals,
|
|
||||||
assertMatch,
|
|
||||||
} from "https://deno.land/std@0.135.0/testing/asserts.ts";
|
|
||||||
import { parsePngInfo } from "./sd.ts";
|
|
||||||
|
|
||||||
Deno.test("parses pnginfo", async (t) => {
|
|
||||||
await t.step("1", () => {
|
|
||||||
const params = parsePngInfo(
|
|
||||||
`female, red fox, pink hair, (long hair), eyeshadow, lipstick, armband, midriff, leather shorts, (fishnet) legwear, fingerless gloves, <3, tongue out,
|
|
||||||
presenting breasts, ((flashing)) breasts, shirt lift, raised shirt, public exposure,
|
|
||||||
lgbt pride, pride colors, pride color clothing, flag \\(object\\), pride march, public,
|
|
||||||
braeburned, keadonger, zaush, jishinu, pixelsketcher, detailed background, insane detail, soft shading, masterpiece
|
|
||||||
Negative prompt: bad-hands-5, boring_e621
|
|
||||||
Steps: 40, Sampler: Euler a, CFG scale: 8, Seed: 2843818575, Size: 768x768, Model hash: e2d72a81a3, Model: bb95FurryMix_v90, Denoising strength: 0.28,
|
|
||||||
SD upscale overlap: 64, SD upscale upscaler: Lanczos, Version: v1.4.0`,
|
|
||||||
);
|
|
||||||
assertMatch(params.prompt ?? "", /\blong hair\b/);
|
|
||||||
assertMatch(params.prompt ?? "", /\bflag \\\(object\\\)/);
|
|
||||||
assertMatch(params.prompt ?? "", /\bmasterpiece\b/);
|
|
||||||
assert(!params.prompt?.includes("2843818575"));
|
|
||||||
assertMatch(params.negative_prompt ?? "", /\bbad-hands-5\b/);
|
|
||||||
assertMatch(params.negative_prompt ?? "", /\bboring_e621\b/);
|
|
||||||
assert(!params.negative_prompt?.includes("2843818575"));
|
|
||||||
assertEquals(params.steps, 40);
|
|
||||||
assertEquals(params.cfg_scale, 8);
|
|
||||||
assertEquals(params.width, 768);
|
|
||||||
assertEquals(params.height, 768);
|
|
||||||
});
|
|
||||||
|
|
||||||
await t.step("2", () => {
|
|
||||||
const params = parsePngInfo(
|
|
||||||
`anthro, female, wolf:1.2, long hair, fluffy tail, thick thighs,
|
|
||||||
wraps, loincloth, tribal clothing, tribal body markings, bone necklace, feathers in hair, skimpy,
|
|
||||||
holding spear, weapon, crouching, digitigrade, action pose, perspective, motion lines, forest, hunting, female pred, grin, angry,
|
|
||||||
by kenket, by ruaidri, by keadonger, by braeburned, by twiren, detailed fur, hires, masterpiece, <lora:add_detail:0.8>
|
|
||||||
Negative prompt: boring_e621_fluffyrock
|
|
||||||
Steps: 40, Sampler: Euler a, CFG scale: 7, Seed: 2876880391, Size: 1536x1536, Model hash: 06ac6055bd,
|
|
||||||
Model: fluffyrock-576-704-832-960-1088-lion-low-lr-e61-terminal-snr-e34, Denoising strength: 0.2,
|
|
||||||
Ultimate SD upscale upscaler: None, Ultimate SD upscale tile_width: 768, Ultimate SD upscale tile_height: 768,
|
|
||||||
Ultimate SD upscale mask_blur: 8, Ultimate SD upscale padding: 48,
|
|
||||||
Lora hashes: "add_detail: 7c6bad76eb54", Version: v1.3.2`,
|
|
||||||
);
|
|
||||||
assertMatch(params.prompt ?? "", /\bwolf\b/);
|
|
||||||
assertMatch(params.prompt ?? "", /\bdigitigrade\b/);
|
|
||||||
assertMatch(params.prompt ?? "", /\bby ruaidri\b/);
|
|
||||||
assert(!params.prompt?.includes("7c6bad76eb54"));
|
|
||||||
assert(!params.prompt?.includes("tile_width"));
|
|
||||||
assert(!params.prompt?.includes("boring_e621_fluffyrock"));
|
|
||||||
assertMatch(params.negative_prompt ?? "", /\bboring_e621_fluffyrock\b/);
|
|
||||||
assert(!params.negative_prompt?.includes("7c6bad76eb54"));
|
|
||||||
assert(!params.negative_prompt?.includes("tile_width"));
|
|
||||||
assert(!params.negative_prompt?.includes("add_detail"));
|
|
||||||
assertEquals(params.steps, 40);
|
|
||||||
assertEquals(params.cfg_scale, 7);
|
|
||||||
assertEquals(params.width, 1536);
|
|
||||||
assertEquals(params.height, 1536);
|
|
||||||
});
|
|
||||||
|
|
||||||
await t.step("3", () => {
|
|
||||||
const params = parsePngInfo(
|
|
||||||
`anthro, female, red fox, long black hair with pink highlights, bra, underwear, digitigrade, pawpads, foot focus, foot fetish, sitting, 4 toes,
|
|
||||||
sticker, outline, simple background, by braeburned, by alibi-cami, by ultrabondagefairy, by dripponi, <lora:easy_sticker:0.5>
|
|
||||||
Negative prompt: boring_e621_v4, happy, smile,
|
|
||||||
Steps: 40, Sampler: Euler a, CFG scale: 7, Seed: 3154849350, Size: 512x512, Model hash: fd926f7598, Model: bb95FurryMix_v100,
|
|
||||||
Denoising strength: 0.65, Lora hashes: "easy_sticker: 2c98dc945091", Version: v1.3.2`,
|
|
||||||
);
|
|
||||||
assertMatch(params.prompt ?? "", /\bbra\b/);
|
|
||||||
assertMatch(params.prompt ?? "", /\blora:easy_sticker\b/);
|
|
||||||
assert(!params.prompt?.includes("smile"));
|
|
||||||
assert(!params.prompt?.includes("Euler a"));
|
|
||||||
assert(!params.prompt?.includes("bb95FurryMix_v100"));
|
|
||||||
assertMatch(params.negative_prompt ?? "", /\bboring_e621_v4\b/);
|
|
||||||
assert(!params.negative_prompt?.includes("simple background"));
|
|
||||||
assert(!params.negative_prompt?.includes("easy_sticker"));
|
|
||||||
assert(!params.negative_prompt?.includes("bb95FurryMix_v100"));
|
|
||||||
assertEquals(params.steps, 40);
|
|
||||||
assertEquals(params.cfg_scale, 7);
|
|
||||||
assertEquals(params.width, 512);
|
|
||||||
assertEquals(params.height, 512);
|
|
||||||
});
|
|
||||||
});
|
|
21
sd.ts
21
sd.ts
@ -52,7 +52,7 @@ export async function sdTxt2Img(
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
while (true) {
|
while (true) {
|
||||||
await Async.abortable(Promise.race([request, Async.delay(4000)]), signal);
|
await Async.abortable(Promise.race([request, Async.delay(3000)]), signal);
|
||||||
if (await AsyncX.promiseState(request) !== "pending") return await request;
|
if (await AsyncX.promiseState(request) !== "pending") return await request;
|
||||||
onProgress?.(await fetchSdApi<SdProgressResponse>(api, "sdapi/v1/progress"));
|
onProgress?.(await fetchSdApi<SdProgressResponse>(api, "sdapi/v1/progress"));
|
||||||
}
|
}
|
||||||
@ -249,20 +249,15 @@ export function parsePngInfo(pngInfo: string): Partial<SdTxt2ImgRequest> {
|
|||||||
const prompt: string[] = [];
|
const prompt: string[] = [];
|
||||||
const negativePrompt: string[] = [];
|
const negativePrompt: string[] = [];
|
||||||
for (const tag of tags) {
|
for (const tag of tags) {
|
||||||
const paramValuePair = tag.trim().match(/^(\w+\s*\w*):\s+(.*)$/u);
|
const paramValuePair = tag.trim().match(/^(\w+\s*\w*):\s+([\d\w. ]+)\s*$/u);
|
||||||
if (paramValuePair) {
|
if (paramValuePair) {
|
||||||
const [, param, value] = paramValuePair;
|
const [, param, value] = paramValuePair;
|
||||||
switch (param.replace(/\s+/u, "").toLowerCase()) {
|
switch (param.replace(/\s+/u, "").toLowerCase()) {
|
||||||
case "positiveprompt":
|
|
||||||
case "positive":
|
|
||||||
case "prompt":
|
case "prompt":
|
||||||
case "pos":
|
|
||||||
part = "prompt";
|
part = "prompt";
|
||||||
prompt.push(value.trim());
|
prompt.push(value.trim());
|
||||||
break;
|
break;
|
||||||
case "negativeprompt":
|
case "negativeprompt":
|
||||||
case "negative":
|
|
||||||
case "neg":
|
|
||||||
part = "negative_prompt";
|
part = "negative_prompt";
|
||||||
negativePrompt.push(value.trim());
|
negativePrompt.push(value.trim());
|
||||||
break;
|
break;
|
||||||
@ -274,7 +269,6 @@ export function parsePngInfo(pngInfo: string): Partial<SdTxt2ImgRequest> {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case "cfgscale":
|
case "cfgscale":
|
||||||
case "cfg":
|
|
||||||
case "detail": {
|
case "detail": {
|
||||||
part = "params";
|
part = "params";
|
||||||
const cfgScale = Number(value.trim());
|
const cfgScale = Number(value.trim());
|
||||||
@ -294,17 +288,6 @@ export function parsePngInfo(pngInfo: string): Partial<SdTxt2ImgRequest> {
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case "seed":
|
|
||||||
case "model":
|
|
||||||
case "modelhash":
|
|
||||||
case "modelname":
|
|
||||||
case "sampler":
|
|
||||||
case "denoisingstrength":
|
|
||||||
case "denoising":
|
|
||||||
case "denoise":
|
|
||||||
part = "params";
|
|
||||||
// ignore for now
|
|
||||||
break;
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -1,14 +1,4 @@
|
|||||||
import {
|
import { Base64, FileType, FmtDuration, Grammy, GrammyParseMode, IKV, Log } from "../deps.ts";
|
||||||
Async,
|
|
||||||
Base64,
|
|
||||||
FileType,
|
|
||||||
FmtDuration,
|
|
||||||
Grammy,
|
|
||||||
GrammyParseMode,
|
|
||||||
GrammyTypes,
|
|
||||||
IKV,
|
|
||||||
Log,
|
|
||||||
} from "../deps.ts";
|
|
||||||
import { bot } from "../bot/mod.ts";
|
import { bot } from "../bot/mod.ts";
|
||||||
import { getGlobalSession, GlobalData, WorkerData } from "../bot/session.ts";
|
import { getGlobalSession, GlobalData, WorkerData } from "../bot/session.ts";
|
||||||
import { fmt, formatUserChat } from "../utils.ts";
|
import { fmt, formatUserChat } from "../utils.ts";
|
||||||
@ -53,7 +43,7 @@ export async function processJobs(): Promise<never> {
|
|||||||
if (err instanceof Grammy.GrammyError || err instanceof SdApiError) {
|
if (err instanceof Grammy.GrammyError || err instanceof SdApiError) {
|
||||||
await bot.api.sendMessage(
|
await bot.api.sendMessage(
|
||||||
job.value.request.chat.id,
|
job.value.request.chat.id,
|
||||||
`Failed to generate your prompt using ${worker.name}: ${err.message}`,
|
`Failed to generate your prompt: ${err.message}`,
|
||||||
{ reply_to_message_id: job.value.request.message_id },
|
{ reply_to_message_id: job.value.request.message_id },
|
||||||
).catch(() => undefined);
|
).catch(() => undefined);
|
||||||
await job.update({ status: { type: "waiting" } }).catch(() => undefined);
|
await job.update({ status: { type: "waiting" } }).catch(() => undefined);
|
||||||
@ -151,6 +141,7 @@ async function processJob(job: IKV.Model<JobSchema>, worker: WorkerData, config:
|
|||||||
job.value.reply.chat.id,
|
job.value.reply.chat.id,
|
||||||
job.value.reply.message_id,
|
job.value.reply.message_id,
|
||||||
`Uploading your images...`,
|
`Uploading your images...`,
|
||||||
|
{ maxAttempts: 1 },
|
||||||
).catch(() => undefined);
|
).catch(() => undefined);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -177,11 +168,6 @@ async function processJob(job: IKV.Model<JobSchema>, worker: WorkerData, config:
|
|||||||
: [],
|
: [],
|
||||||
]);
|
]);
|
||||||
|
|
||||||
let sendMediaAttempt = 0;
|
|
||||||
let resultMessages: GrammyTypes.Message.MediaMessage[] | undefined;
|
|
||||||
while (true) {
|
|
||||||
sendMediaAttempt++;
|
|
||||||
|
|
||||||
// parse files from reply JSON
|
// parse files from reply JSON
|
||||||
const inputFiles = await Promise.all(
|
const inputFiles = await Promise.all(
|
||||||
response.images.map(async (imageBase64, idx) => {
|
response.images.map(async (imageBase64, idx) => {
|
||||||
@ -199,23 +185,14 @@ async function processJob(job: IKV.Model<JobSchema>, worker: WorkerData, config:
|
|||||||
);
|
);
|
||||||
|
|
||||||
// send the result to telegram
|
// send the result to telegram
|
||||||
try {
|
const resultMessage = await bot.api.sendMediaGroup(job.value.request.chat.id, inputFiles, {
|
||||||
resultMessages = await bot.api.sendMediaGroup(job.value.request.chat.id, inputFiles, {
|
|
||||||
reply_to_message_id: job.value.request.message_id,
|
reply_to_message_id: job.value.request.message_id,
|
||||||
maxAttempts: 5,
|
maxAttempts: 5,
|
||||||
});
|
});
|
||||||
break;
|
|
||||||
} catch (err) {
|
|
||||||
logger().warning(`Sending images (attempt ${sendMediaAttempt}) failed: ${err}`);
|
|
||||||
if (sendMediaAttempt >= 5) throw err;
|
|
||||||
await Async.delay(15000);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// send caption in separate message if it couldn't fit
|
// send caption in separate message if it couldn't fit
|
||||||
if (caption.text.length > 1024 && caption.text.length <= 4096) {
|
if (caption.text.length > 1024 && caption.text.length <= 4096) {
|
||||||
await bot.api.sendMessage(job.value.request.chat.id, caption.text, {
|
await bot.api.sendMessage(job.value.request.chat.id, caption.text, {
|
||||||
reply_to_message_id: resultMessages[0].message_id,
|
reply_to_message_id: resultMessage[0].message_id,
|
||||||
entities: caption.entities,
|
entities: caption.entities,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -233,9 +210,7 @@ async function processJob(job: IKV.Model<JobSchema>, worker: WorkerData, config:
|
|||||||
status: { type: "done", info: response.info, startDate, endDate: new Date() },
|
status: { type: "done", info: response.info, startDate, endDate: new Date() },
|
||||||
});
|
});
|
||||||
logger().debug(
|
logger().debug(
|
||||||
`Job finished for ${formatUserChat(job.value.request)} using ${worker.name}${
|
`Job finished for ${formatUserChat(job.value.request)} using ${worker.name}`,
|
||||||
sendMediaAttempt > 1 ? ` after ${sendMediaAttempt} attempts` : ""
|
|
||||||
}`,
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user