Compare commits
9 Commits
c491996a5d
...
51db4ba9b5
| Author | SHA1 | Date | |
|---|---|---|---|
| 51db4ba9b5 | |||
| c98528a54f | |||
| 2f0f10eed9 | |||
| 8bec34413f | |||
| b8b3895310 | |||
| 5b84376dc7 | |||
| 69ae37e05e | |||
| edcc0ddc91 | |||
| 751a0a1e15 |
@@ -2,7 +2,7 @@ import {ChatCommand} from "../base/chat-command";
|
|||||||
import {Message} from "typescript-telegram-bot-api";
|
import {Message} from "typescript-telegram-bot-api";
|
||||||
import {Requirements} from "../base/requirements";
|
import {Requirements} from "../base/requirements";
|
||||||
import {Requirement} from "../base/requirement";
|
import {Requirement} from "../base/requirement";
|
||||||
import {bot, openAi, photoDir} from "../index";
|
import {bot, openAi, photoGenDir} from "../index";
|
||||||
import fs from "node:fs";
|
import fs from "node:fs";
|
||||||
import path from "node:path";
|
import path from "node:path";
|
||||||
import {editMessageText, logError, replyToMessage} from "../util/utils";
|
import {editMessageText, logError, replyToMessage} from "../util/utils";
|
||||||
@@ -27,14 +27,9 @@ export class OpenAIGenImage extends ChatCommand {
|
|||||||
try {
|
try {
|
||||||
const totalParts = 3;
|
const totalParts = 3;
|
||||||
const model = Environment.OPENAI_IMAGE_MODEL;
|
const model = Environment.OPENAI_IMAGE_MODEL;
|
||||||
const size = "1024x1024";
|
|
||||||
const fileFullName = `${msg.chat.id}_${msg.message_id}.png`;
|
const fileFullName = `${msg.chat.id}_${msg.message_id}.png`;
|
||||||
const getFileLocation = (fn: string) => {
|
const getFileLocation = (fn: string) => {
|
||||||
const genRoot = path.join(photoDir, "gen");
|
return path.join(photoGenDir, fn);
|
||||||
if (!fs.existsSync(genRoot)) {
|
|
||||||
fs.mkdirSync(genRoot);
|
|
||||||
}
|
|
||||||
return path.join(genRoot, fn);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
waitMessage = await replyToMessage({message: msg, text: "🌈 Генерирую изображение..."});
|
waitMessage = await replyToMessage({message: msg, text: "🌈 Генерирую изображение..."});
|
||||||
@@ -43,9 +38,11 @@ export class OpenAIGenImage extends ChatCommand {
|
|||||||
model: model,
|
model: model,
|
||||||
prompt: prompt,
|
prompt: prompt,
|
||||||
n: 1,
|
n: 1,
|
||||||
size: size,
|
size: "auto",
|
||||||
stream: true,
|
stream: true,
|
||||||
partial_images: totalParts,
|
partial_images: totalParts,
|
||||||
|
moderation: "low",
|
||||||
|
output_format: "png",
|
||||||
});
|
});
|
||||||
|
|
||||||
const then = Date.now();
|
const then = Date.now();
|
||||||
@@ -89,7 +86,7 @@ export class OpenAIGenImage extends ChatCommand {
|
|||||||
media: {
|
media: {
|
||||||
type: "photo",
|
type: "photo",
|
||||||
media: imageBuffer,
|
media: imageBuffer,
|
||||||
caption: `🌈 Изображение по запросу "${prompt}" сгенерировано моделью "${model}" размеров ${size} за ${diff}ms`
|
caption: `🌈 Изображение по запросу "${prompt}" сгенерировано моделью "${model}" размеров ${event.size} за ${diff}ms`
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -12,8 +12,7 @@ import {
|
|||||||
getUserAvatar,
|
getUserAvatar,
|
||||||
logError,
|
logError,
|
||||||
makeDarkGradientBgFancy,
|
makeDarkGradientBgFancy,
|
||||||
oldReplyToMessage,
|
replyToMessage
|
||||||
oldSendMessage
|
|
||||||
} from "../util/utils";
|
} from "../util/utils";
|
||||||
import {Requirements} from "../base/requirements";
|
import {Requirements} from "../base/requirements";
|
||||||
import {Requirement} from "../base/requirement";
|
import {Requirement} from "../base/requirement";
|
||||||
@@ -50,15 +49,10 @@ export class Quote extends Command {
|
|||||||
const chatId = msg.chat.id;
|
const chatId = msg.chat.id;
|
||||||
const reply = msg.reply_to_message;
|
const reply = msg.reply_to_message;
|
||||||
|
|
||||||
if (!reply) {
|
|
||||||
await oldReplyToMessage(msg, "Сделай /quote реплаем на сообщение 🙂").catch(logError);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const quoteRaw = (msg.quote?.text ?? reply.text ?? reply.caption ?? "").trim();
|
const quoteRaw = (msg.quote?.text ?? reply.text ?? reply.caption ?? "").trim();
|
||||||
if (quoteRaw.length === 0) {
|
if (quoteRaw.length === 0) {
|
||||||
await oldReplyToMessage(msg, "Не нашёл в сообщении текста 😢").catch(logError);
|
await replyToMessage({message: msg, text: "Не нашёл в сообщении текста 😢"}).catch(logError);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -76,7 +70,7 @@ export class Quote extends Command {
|
|||||||
}).catch(logError);
|
}).catch(logError);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
logError(e);
|
logError(e);
|
||||||
await oldSendMessage(msg, "Не смог собрать цитату 😢").catch(logError);
|
await replyToMessage({message: msg, text: "Не смог собрать цитату 😢"}).catch(logError);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,6 +19,8 @@ export class Environment {
|
|||||||
|
|
||||||
static ONLY_FOR_CREATOR_MODE: boolean;
|
static ONLY_FOR_CREATOR_MODE: boolean;
|
||||||
|
|
||||||
|
static ENABLE_UNSAFE_EVAL: boolean;
|
||||||
|
|
||||||
static ANSWERS: Answers;
|
static ANSWERS: Answers;
|
||||||
|
|
||||||
static USE_NAMES_IN_PROMPT: boolean;
|
static USE_NAMES_IN_PROMPT: boolean;
|
||||||
@@ -65,6 +67,8 @@ export class Environment {
|
|||||||
|
|
||||||
Environment.ONLY_FOR_CREATOR_MODE = ifTrue(process.env.ONLY_FOR_CREATOR_MODE);
|
Environment.ONLY_FOR_CREATOR_MODE = ifTrue(process.env.ONLY_FOR_CREATOR_MODE);
|
||||||
|
|
||||||
|
Environment.ENABLE_UNSAFE_EVAL = ifTrue(process.env.ENABLE_UNSAFE_EVAL);
|
||||||
|
|
||||||
Environment.USE_NAMES_IN_PROMPT = ifTrue(process.env.USE_NAMES_IN_PROMPT);
|
Environment.USE_NAMES_IN_PROMPT = ifTrue(process.env.USE_NAMES_IN_PROMPT);
|
||||||
|
|
||||||
Environment.MAX_PHOTO_SIZE = Number(process.env.MAX_PHOTO_SIZE || "1280");
|
Environment.MAX_PHOTO_SIZE = Number(process.env.MAX_PHOTO_SIZE || "1280");
|
||||||
|
|||||||
+18
-12
@@ -4,7 +4,6 @@ import {TelegramBot, User} from "typescript-telegram-bot-api";
|
|||||||
import {Command} from "./base/command";
|
import {Command} from "./base/command";
|
||||||
import {
|
import {
|
||||||
delay,
|
delay,
|
||||||
ignore,
|
|
||||||
initSystemSpecs,
|
initSystemSpecs,
|
||||||
logError,
|
logError,
|
||||||
processCallbackQuery,
|
processCallbackQuery,
|
||||||
@@ -132,7 +131,6 @@ export const commands: Command[] = [
|
|||||||
new Start(),
|
new Start(),
|
||||||
new Help(),
|
new Help(),
|
||||||
new Test(),
|
new Test(),
|
||||||
new Ae(),
|
|
||||||
new Ignore(),
|
new Ignore(),
|
||||||
new Unignore(),
|
new Unignore(),
|
||||||
new Ping(),
|
new Ping(),
|
||||||
@@ -168,6 +166,10 @@ export const commands: Command[] = [
|
|||||||
new YouTubeDownload()
|
new YouTubeDownload()
|
||||||
];
|
];
|
||||||
|
|
||||||
|
if (Environment.ENABLE_UNSAFE_EVAL) {
|
||||||
|
commands.push(new Ae());
|
||||||
|
}
|
||||||
|
|
||||||
export const callbackCommands: CallbackCommand[] = [
|
export const callbackCommands: CallbackCommand[] = [
|
||||||
new OllamaCancel()
|
new OllamaCancel()
|
||||||
];
|
];
|
||||||
@@ -215,8 +217,10 @@ if (Environment.OPENAI_API_KEY) {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
export const photoDir = path.join(Environment.DATA_PATH, "photo");
|
export const cacheDir = path.join(Environment.DATA_PATH, "cache");
|
||||||
export const videoDir = path.join(Environment.DATA_PATH, "video");
|
export const photoDir = path.join(cacheDir, "photo");
|
||||||
|
export const photoGenDir = path.join(photoDir, "gen");
|
||||||
|
export const videoDir = path.join(cacheDir, "video");
|
||||||
|
|
||||||
let isShuttingDown = false;
|
let isShuttingDown = false;
|
||||||
|
|
||||||
@@ -246,8 +250,12 @@ async function main() {
|
|||||||
`DEFAULT_AI_PROVIDER: ${Environment.DEFAULT_AI_PROVIDER}`
|
`DEFAULT_AI_PROVIDER: ${Environment.DEFAULT_AI_PROVIDER}`
|
||||||
);
|
);
|
||||||
|
|
||||||
fs.mkdir(photoDir, ignore);
|
const dirsToCheck = [cacheDir, photoDir, photoGenDir, videoDir];
|
||||||
fs.mkdir(videoDir, ignore);
|
dirsToCheck.forEach(dir => {
|
||||||
|
if (!fs.existsSync(dir)) {
|
||||||
|
fs.mkdirSync(dir);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
const now = new Date();
|
const now = new Date();
|
||||||
|
|
||||||
@@ -256,15 +264,13 @@ async function main() {
|
|||||||
midnight.setDate(now.getDate() + 1);
|
midnight.setDate(now.getDate() + 1);
|
||||||
|
|
||||||
const diff = midnight.getTime() - now.getTime();
|
const diff = midnight.getTime() - now.getTime();
|
||||||
console.log("Clearing up videos and photos will be started in " + diff + "ms");
|
console.log("Clearing up cache will be started in " + diff + "ms");
|
||||||
|
|
||||||
clearUpFolderFromOldFiles(videoDir);
|
clearUpFolderFromOldFiles(cacheDir);
|
||||||
clearUpFolderFromOldFiles(photoDir);
|
|
||||||
delay(diff).then(() => {
|
delay(diff).then(() => {
|
||||||
setInterval(() => {
|
setInterval(() => {
|
||||||
console.log("Started clearing up videos and photos");
|
console.log("Started clearing up cache");
|
||||||
clearUpFolderFromOldFiles(videoDir);
|
clearUpFolderFromOldFiles(cacheDir);
|
||||||
clearUpFolderFromOldFiles(photoDir);
|
|
||||||
}, 1000 * 60 * 60 * 24);
|
}, 1000 * 60 * 60 * 24);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
+22
-19
@@ -2,7 +2,7 @@ import {logError} from "./utils";
|
|||||||
import fs from "node:fs";
|
import fs from "node:fs";
|
||||||
import path from "node:path";
|
import path from "node:path";
|
||||||
|
|
||||||
export function clearUpFolderFromOldFiles(folder: string) {
|
export function clearUpFolderFromOldFiles(folder: string, recursive = true) {
|
||||||
fs.readdir(folder, (err, files) => {
|
fs.readdir(folder, (err, files) => {
|
||||||
if (err) {
|
if (err) {
|
||||||
logError(err);
|
logError(err);
|
||||||
@@ -11,32 +11,35 @@ export function clearUpFolderFromOldFiles(folder: string) {
|
|||||||
|
|
||||||
const filenamesToDelete: string[] = [];
|
const filenamesToDelete: string[] = [];
|
||||||
|
|
||||||
files.forEach((filename, index) => {
|
files.forEach(filename => {
|
||||||
fs.stat(path.join(folder, filename), (err, stats) => {
|
const fullPath = path.join(folder, filename);
|
||||||
if (err) {
|
|
||||||
logError(err);
|
try {
|
||||||
|
const stats = fs.statSync(fullPath);
|
||||||
|
if (stats.isDirectory() && recursive) {
|
||||||
|
clearUpFolderFromOldFiles(fullPath, recursive);
|
||||||
} else {
|
} else {
|
||||||
const then = stats.mtime.getTime() / 1000;
|
const then = stats.mtime.getTime() / 1000;
|
||||||
const now = Date.now() / 1000;
|
const now = Date.now() / 1000;
|
||||||
const diff = Math.abs(now - then);
|
const diff = Math.abs(now - then);
|
||||||
const moreThanOneDay = diff >= 60 * 60 * 24;
|
const moreThanOneDay = diff >= 60 * 60 * 24;
|
||||||
if (moreThanOneDay) {
|
|
||||||
filenamesToDelete.push(filename);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (index === files.length - 1) {
|
if (stats.isFile() && moreThanOneDay) {
|
||||||
console.log("filenamesToDelete", filenamesToDelete);
|
filenamesToDelete.push(fullPath);
|
||||||
if (filenamesToDelete.length) {
|
|
||||||
filenamesToDelete.forEach((filename) => {
|
|
||||||
const fullPath = path.join(folder, filename);
|
|
||||||
fs.rm(fullPath, (e) => {
|
|
||||||
if (e) logError(e);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
} catch (e) {
|
||||||
|
logError(e);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
console.log("filenamesToDelete", filenamesToDelete);
|
||||||
|
if (filenamesToDelete.length) {
|
||||||
|
filenamesToDelete.forEach((filename) => {
|
||||||
|
fs.rm(filename, (e) => {
|
||||||
|
if (e) logError(e);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
+5
-15
@@ -15,7 +15,7 @@ import {
|
|||||||
} from "typescript-telegram-bot-api";
|
} from "typescript-telegram-bot-api";
|
||||||
import {Environment} from "../common/environment";
|
import {Environment} from "../common/environment";
|
||||||
import {TelegramError} from "typescript-telegram-bot-api/dist/errors";
|
import {TelegramError} from "typescript-telegram-bot-api/dist/errors";
|
||||||
import {bot, botUser, callbackCommands, commands, messageDao, ollama} from "../index";
|
import {bot, botUser, callbackCommands, commands, messageDao, ollama, photoDir} from "../index";
|
||||||
import os from "os";
|
import os from "os";
|
||||||
import axios from "axios";
|
import axios from "axios";
|
||||||
import {MessagePart} from "../common/message-part";
|
import {MessagePart} from "../common/message-part";
|
||||||
@@ -538,12 +538,7 @@ export async function loadImagesIfExists(msg: Message | StoredMessage): Promise<
|
|||||||
|
|
||||||
const maxSize = await mapPhotoSizeToMax(getPhotoMaxSize(msg.photo));
|
const maxSize = await mapPhotoSizeToMax(getPhotoMaxSize(msg.photo));
|
||||||
if (maxSize) {
|
if (maxSize) {
|
||||||
const imagePath = path.join(Environment.DATA_PATH, "photo");
|
let imageFilePath = path.join(photoDir, maxSize.unique_file_id + ".jpg");
|
||||||
if (!fs.existsSync(imagePath)) {
|
|
||||||
fs.mkdirSync(imagePath);
|
|
||||||
}
|
|
||||||
|
|
||||||
let imageFilePath = path.join(imagePath, maxSize.unique_file_id + ".jpg");
|
|
||||||
if (!fs.existsSync(imageFilePath)) {
|
if (!fs.existsSync(imageFilePath)) {
|
||||||
const res = await axios.get<ArrayBuffer>(maxSize.url, {responseType: "arraybuffer"});
|
const res = await axios.get<ArrayBuffer>(maxSize.url, {responseType: "arraybuffer"});
|
||||||
const src = Buffer.from(res.data);
|
const src = Buffer.from(res.data);
|
||||||
@@ -567,11 +562,6 @@ export async function loadImagesIfExists(msg: Message | StoredMessage): Promise<
|
|||||||
export async function loadImagesFromFileIds(sizes: PhotoSize[]): Promise<string[] | null> {
|
export async function loadImagesFromFileIds(sizes: PhotoSize[]): Promise<string[] | null> {
|
||||||
if (!sizes?.length) return null;
|
if (!sizes?.length) return null;
|
||||||
|
|
||||||
const dataPath = path.join(Environment.DATA_PATH, "photo");
|
|
||||||
if (!fs.existsSync(dataPath)) {
|
|
||||||
fs.mkdirSync(dataPath);
|
|
||||||
}
|
|
||||||
|
|
||||||
const existing =
|
const existing =
|
||||||
sizes.filter(s => fs.existsSync(photoPathByUniqueId(s.file_unique_id)))
|
sizes.filter(s => fs.existsSync(photoPathByUniqueId(s.file_unique_id)))
|
||||||
.map(s => s.file_unique_id);
|
.map(s => s.file_unique_id);
|
||||||
@@ -589,7 +579,7 @@ export async function loadImagesFromFileIds(sizes: PhotoSize[]): Promise<string[
|
|||||||
const paths = responses.map((res, index) => {
|
const paths = responses.map((res, index) => {
|
||||||
try {
|
try {
|
||||||
const uniqueFileId = maxSizes[index].unique_file_id;
|
const uniqueFileId = maxSizes[index].unique_file_id;
|
||||||
const imageFilePath = path.join(dataPath, uniqueFileId + ".jpg");
|
const imageFilePath = path.join(photoDir, uniqueFileId + ".jpg");
|
||||||
const src = Buffer.from(res.data);
|
const src = Buffer.from(res.data);
|
||||||
fs.writeFileSync(imageFilePath, src);
|
fs.writeFileSync(imageFilePath, src);
|
||||||
return uniqueFileId;
|
return uniqueFileId;
|
||||||
@@ -1063,7 +1053,7 @@ async function processAlbum(groupId: string): Promise<string[]> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function photoPathByUniqueId(uniqueId: string): string {
|
export function photoPathByUniqueId(uniqueId: string): string {
|
||||||
return path.join(Environment.DATA_PATH, "photo", uniqueId + ".jpg");
|
return path.join(photoDir, uniqueId + ".jpg");
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getCurrentModel(): string {
|
export function getCurrentModel(): string {
|
||||||
@@ -1149,7 +1139,7 @@ export async function processNewMessage(msg: Message): Promise<void> {
|
|||||||
logError(e);
|
logError(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((msg.new_chat_members?.length || 0 > 0)) {
|
if ((msg.new_chat_members?.length)) {
|
||||||
await bot.sendMessage({chat_id: msg.chat.id, text: randomValue(Environment.ANSWERS.invite)}).catch(logError);
|
await bot.sendMessage({chat_id: msg.chat.id, text: randomValue(Environment.ANSWERS.invite)}).catch(logError);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-7
@@ -1,7 +1,7 @@
|
|||||||
import Innertube, {Platform, Types, Utils} from "youtubei.js";
|
import Innertube, {Platform, Types, Utils} from "youtubei.js";
|
||||||
import fs, {createWriteStream} from "node:fs";
|
import fs, {createWriteStream} from "node:fs";
|
||||||
import path from "node:path";
|
import path from "node:path";
|
||||||
import {Environment} from "../common/environment";
|
import {videoDir} from "../index";
|
||||||
|
|
||||||
export function getYouTubeVideoId(url: string): string {
|
export function getYouTubeVideoId(url: string): string {
|
||||||
const regex = /(?:(?:youtube\.com|music\.youtube\.com)\/(?:[^\/]+\/.+\/|(?:v|e(?:mbed)?|shorts|clip)\/|.*[?&]v=)|youtu\.be\/)([^"&?/\s]{11})/i;
|
const regex = /(?:(?:youtube\.com|music\.youtube\.com)\/(?:[^\/]+\/.+\/|(?:v|e(?:mbed)?|shorts|clip)\/|.*[?&]v=)|youtu\.be\/)([^"&?/\s]{11})/i;
|
||||||
@@ -20,12 +20,7 @@ export async function downloadVideoFromYouTube(url: string, targetQuality: strin
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
const videoId = getYouTubeVideoId(url);
|
const videoId = getYouTubeVideoId(url);
|
||||||
const videoFolder = path.join(Environment.DATA_PATH, "video");
|
const filePath = path.join(videoDir, `${videoId}.mp4`);
|
||||||
if (!fs.existsSync(videoFolder)) {
|
|
||||||
fs.mkdirSync(videoFolder);
|
|
||||||
}
|
|
||||||
|
|
||||||
const filePath = path.join(videoFolder, `${videoId}.mp4`);
|
|
||||||
if (fs.existsSync(filePath)) {
|
if (fs.existsSync(filePath)) {
|
||||||
const buffer = Buffer.from(fs.readFileSync(filePath));
|
const buffer = Buffer.from(fs.readFileSync(filePath));
|
||||||
return {
|
return {
|
||||||
|
|||||||
Reference in New Issue
Block a user