Catpy (Cat + Python) - чат бот ВКонтакте, разработанный Catware, и фактически являющийся ее главным проектом за счет преимущества в количестве пользователей. Ко всему печальному, оно падает, а бот медленно разлагается где-то на agrik-srv1, однопоточно выполняя команды и обрабатывая события. Основывается на CatABMS.

Впрочем-то, данная статья просто собирает в себе текста других статей, поэтому читайте и наслаждайтесь.

CatABMS

CatABMS (Catware Advanced Bot Manipulating System, Расширенная Система Управления Ботами Catware) - разработанный Catware, и до сих пор не вышедший в свет (почти) синхронный фреймворк для создания ботов для социальной сети ВКонтакте. Имеет несколько ответвлений.

Структура системы

Система выполнена в стандарте CFHS - Catware File Hierarhy System, аналог для FHS:

chains - файлы CatABMS Chains

chats - БД чатов

commands - исполняемые файлы и конфиги команд

configs - конфигурационные файлы CatABMS

corerc - Файлы CoreRC (Core Running Commands), выполняющиеся при получении сообщения.

exf - исполняемые файлы CatShell

json - модифицируемые системой конфигурационные файлы

lib - библиотеки, необходимые для работы ядра или иных компонентов системы

modules - конфигурационные файлы системы модулей

services - исполняемые файлы Catware Autostart, выполняющиеся при старте бота

tmp - временные файлы, которые удаляются CoreRC-модулем CSM (Catware Space Manager).

users - БД пользователей

catenv.py - файл с взаимосвязанными DEFами, необходимыми для работы системы - фактически API системы.

core.py - ядро, обрабатывающее входящие сообщения

faststart.py - загрузчик системы

Структура: Загрузчик

Идёт начальная загрузка модулей: sys, os, psutil.

Далее идёт загрузка CatENV. Файл загружается в память, выполняется и удаляется.

Активируется система автономности: установщик модулей, который за вас установит и импортирует все модули, следуюя логике сетов модулей. Сет модулей состоит из:

  1. Списка модулей, которые необходимо установить через PIP
  2. Строк, которые необходимо выполнить через exec, наподобии import ...
  3. Скрипт иницилизации модулей, которые требуют обозначения их обьекта

Если какой-то из модулей импортировать не удалось, то идёт переустановка всего сета модулей.

Всего их 3:

  1. base-system (Базовые пакеты, которые даже устанавливать не надо)
  2. media (В основном, это модули, работающие с API/парсеры некоторых сервисов)
  3. network (В основном, это те, что коим-то боком работают с сетевым стеком.)

Затем идёт загрузка конфигурационных файлов, в которых содержится полустатическая информация - токен, ID группы, название бота и другая косметическая/не очень информация.

Выполняются функции CatENV - getreportban, getban, getmuted, gettroll.

Определяется операционная система, исходя из значения os.name.

Далее идёт подготовка к запуску ядра.

Система авторизуется во ВКонтакте, бесконечно дёргая при этом метод авторизации, пока не получится залогиниться во ВКонтакте.

Когда залогиниться наконец получается, то управление косвенно передаётся ядру: при нажатии Ctrl+C ядро выгружается из памяти и активируется CatShell - оболочка командой строки, работающая с EXF-файлами (CatShell EXecutable Files)

По команде exit, ядро вновь начинает свою загрузку.

Когда управление передаётся ядру:

Структура: Ядро

Когда управление передано ядру, оно занимается загрузкой библиотек:

  1. detectfull, чтобы при обработке картинок качество не шакалилось
  2. surrogate-manager, ныне не рабочая библиотека
  3. CUMv2 - Catware User Manager второй версии. Работает с БД пользователей и чатов.
  4. generrorcode - генератор индивидуальных кодов ошибок

Далее, идёт загрузка команд из папки, обозначенной в папке ядра, в которой содержатся папки, содержащие .py и .json-файлы, первый является исполняемым исходником, а второй выполняет функцию конфига, который можно подсмотреть в этой статье.

Затем загружаются CoreRC файлы, и выполняется Catware Autostart

Далее начинается бесконечный цикл ядра, поскольку ядро сделано очень криво и крашится каждые 5 минут.

Начинается оно с очистки лишних переменных компонентом Catware MemGun.

Если установлен необходимый параметр, то ядро запускается в безопасном режиме: отвечает только администраторам бота.

Сообщается всем администраторам о запуске бота: сообщается IP сервера, операционная система и хостнейм.

Ядро начинает слушать LongPoll-сервера ВКонтакте на события.

Если получен обьект нового/отредактированного сообщения, полученного НЕ ОТ ГРУППБОТА, то начинается разбор текста сообщения. Если же оно пустое/некорректное, то на событие ставится метка о невыполнении, дабы освободить ядро от лишних нагрузок.

Если же обьект события полностью корректен, то получается следующая информация:

- ID пользователя

- Время получения обьекта события

- Обьект получателя

- Переданная команда

- Переданные параметры

- Переданные флаги

- ID чата, если получено в беседе

Также проверяется, находится ли пользователь в тролльлисте, если есть, то он начинает троллиться текстом, который ему указал администратор, если нет, то обработка продолжается:

  1. Начинается проверка на наличие переданной команды в списке команд
  2. Запускаются модули CoreRC
  3. Проверка на реплаи: если обнаружен реплай и не передан параметр, то текст из реплайнутого сообщения будет использоваться как параметр
  4. Проверка вложений в сообщении
  5. Проверка на значение выполняемого идентификатора цепочки
  6. Если всё соответствует ПЕРВОМУ случаю, то выполняется команда
  7. Если обнаружен ВТОРОЙ случай (команда из списка потенциально оскорбительных команд), проверяется согласие пользователя на то, чтобы выполнить эту команду, если же пакет подключен - она выполняется.
  8. Если обнаружен ТРЕТИЙ случай (команда для тестеров), проверяется наличие метки тестера у пользователя, если она имеется - команда запускается, если нет - пользователь получает соответствующее уведомление и приглашается в программу бета-тестирования
  9. Если же команда при выполнении крашнулась, то багрепорт отправляется админам в нём сообщается вызванная команда, полный Traceback, ID диалога, идентификатор команды, время вызова команды, код ошибки, а пользователю остаётся видеть сообщение об ошибке.
  10. Если обнаружена ошибка, связанная с правами администрирования в том или ином чате, но у бота нет админки в беседе, отправляется соответствующее сообщение
  11. Если обнаружен ЧЕТВЁРТЫЙ СЛУЧАЙ, то задействуется модуль цепочки, указанный у юзера в параметре stage.
  12. Если обнаружен ПЯТЫЙ случай (выход из цепочки), параметр stage попросту обнуляется.
  13. Если же пользователь обнаружен в забаненых, то ничего не выполняется, а пользователь посылается нахуй.

Далее идёт проверка других типов событий:

  1. GROUP_LEAVE = отписавшемуся пользователю пишется в Л/С требование обьяснить своё действие, в целях улучшения бота.
  2. GROUP_JOIN = благодарность за подписку в Л/С.
  3. MESSAGE_REPLY = логирование и подсчёт отправленных сообщений
  4. WALL_POST_NEW = в беседу группы отправляется новая запись на стене бота.
  5. Также идёт проверка нагрузки на оперативную память, если занято больше 90% - сообщается об этом админам.
  6. Очистка памяти инструментом MemGun (Memory Gun)

-- Продолжение следует --

CatLib

CatLib - библиотека для catPY. Сейчас мы покажем вам пример типичного CatLib'a

# CatAPI binds library (Catware)
def cget(arg):
    return Get("http://izzytopdevelop.pythonanywhere.com/api?method=get&arg=" + str(arg) + "&user_id=" + ReadFF("user_id.txt"))
def edit(arg, value): 
    return Get("http://izzytopdevelop.pythonanywhere.com/api?method=privateset&token=" + ReadFF("catapi-token.txt") + "&arg=" + str(arg) + "&user_id=" + ReadFF("user_id.txt") + "&value=" + urllib.parse.quote(str(value)))

А сейчас мы покажем типичный пример использования CatLib'a:

# CatOS-Type Package
author = "catwared"
mode = "start"
deps = 'None'
identificator = 'uname'
command_ru = 'имя'
description = 'Установить имя'
exec(ReadFF("lib/catapi-io.py")) # Импорт библиотеки
edit("username", ReadFF("parameter.txt")) # Использование
message("Ваше имя сменено на " + ReadFF("parameter.txt"))

Создание команд

Перед созданием команд убедитесь, что они соответствуют требованиям Catware:

- команда действительно имеет применение

- команда выполняется как можно быстрее

- команда не использует запрещённых методов

Проверили? Поехали дальше.

Содержание

Создание конфигурации команды

Примерная конфигурация команды выглядит так:

{

"author": "catwared",

"mode": "=",

"deps": "None",

"identificator": "test",

"command_ru": "тест",

"description": "Тестовая команда",

"testing": false,

"hide": false,

"restricted": false,

"disabled": false

}

Поле "author": в него вы вписываете свои данные (никнейм, способ связаться)

Поле "mode": способ реагирования на команду:

Режим использования Описание
= Команда не требует аргументов, либо они опциональны
start Команда ОБЯЗАТЕЛЬНО требует аргумента
pic Команда требует приложенной картинки

Поле deps не нужно, т.к пока что не добавили поддержку/замену

Поле "identificator": идентификатор вашей команды

Поле "command_ru": название (триггер) команды. Не должно содержать пробелов

Поле "description": описание вашей команды.

Флаги:

testing hide restricted disabled
Значение факта команды для тестеров Скрытие команды Команда потенциально оскорбительна? Команда отключена?

Теперь перейдём к выебонам возможностям написания под CatABMS

CatENV

Начнём пожалуй с CatENV - набор определений (методов), сильно упрощающий написание кода.

Название метода Передаваемые аргументы Возможный ответ от функции Что это?
dvn integer 148.0 KB Функция для словестной записи размера данных
allchatrules нет Правила: текст Возвращает правила беседы, где задействован метод во время выполнения команды
setTester id пользователя нет Устанавливает пользователю значение тестера Catpy и сообщает пользователю об этом
unsetTester id пользователя нет Лишает пользователя значения тестера Catpy и сообщает ему об этом.
testerinfo id пользователя {'id': 597100871, 'tester': True, 'reports': 0, 'report_list': [], 'first_invite': 1624988382, 'last_invite': 1624988382, 'status': 'Бета-тестировщик catpy'} Информация о тестировщике в формате JSON
isTester id пользователя True/False Является ли пользователь тестировщиком
ssorg lat, long (int) Возвращаемые значения:

- Рассвет (0)

- Закат (1)

- Астрономический полдень (2)

- Длительность светового дня (3)

- Начало человеческого рассвета (4)

- Конец человеческого заката (5)

- Начало морского рассвета (6)

- Конец морского заката (7)

- Начало астрономического рассвета (8)

- Конец астрономического заката (9)

- Отклонение от UTC (10)

Ума не приложу, зачем нужно большинство этих данных, но пусть будет))

Все данные возвращаются в массиве по порядку в формате unixtime по местному времени

globalid conversation_message_id (int) message_id Не шарю, вроде от этого смски можно группой сносить
regproc Любой текст Нет Создаёт редактируемое сообщение
editmessage Любой текст Нет Редактирует сообщение, созданное методом regproc()
weekday int от 1 до 7 Возвращает день недели по числу Хуй знает зачем это и где используется
chatadmins peer_id (int) Возвращает список ID админов чата Крутая же фича
clrlink URL Возвращает сокращённую ссылку Тож пиздатая фичя((
isgroup user_id Возвращает значение (True/False) факта того группа это или нет Ну, хз зачем блять нахуй это надо сука
cordstooffset lat, lon (int) Возвращает смещение по геокоординатам (не помню чё там в жсоне, да и неибу, спросите у катвиерда/зиги) cords to offset
readabledate unixtime (int) Возвращает читаемую дату юникстайм в дату
rid нет Бинд для быстрой генерации random_id для ВКонтакте, возвращаает рандомное число лень просто вводить каждый раз рандд. ранддинт чёто там...
strike Любой текст Любой текст Фишка юникода
HostToIp URL 123.123.123.123 Получение IP из домена
percent сколько всего, сколько из "всего" 53.0 Получение процента
getid короткое имя ВКонтакте 131236782 Получение цифрового ID пользователя
getmention user_id [id123123123|Имя Фамилия] Получение упоминания пользователя
getname user_id Имя Фамилия Получение имени пользователя по ID
convertjson strинговый жсон жсоновый жсон Тупо бинд для json.loads
translate text, lang Переведённый текст Переводчик (коды языков смотреть в документации googletrans python))))
Voice /path/to/ogg Нет Записывает голосовое сообщение
PlusWrite текст, путь/к/файлу Нет Дозапись в файл
Get URL Полученный текст GET-запрос
InstallPackage название пакета в PIP Нет Устанавливает pip пакетик йойойойо
ReadFF путь/к/файлу Содержимое файла Читает файл и возвращает его содержимое
CallSystem команда в Linux Shell Выхлоп команды Вызов шела
Run путь/к/файлу Зависит от кода Хз зачем эта хуйня
RunThread id потока, def, (args,) Нет Тоже не ебу, но это поток, да
convertint 19834273847 229563 дня 8 часов 30 минут 47 секунд Словестная запись количества секунд
Download URL, /path/to/download Нет Скачивание файла
similar первая строка, вторая строка True/False Сравнение строк на схожесть
TextToBits строка 1000101010101010101000101010100101 бинарное кодирование короч да понели Двоичное кодирование
TextFromBits 10010111010001010 ебаные строка Двоичное декодирование
Reverse строка акортс Реверсирование текста
RandomLetter нет Рандомная латинская буква Рандомная буква
writeTo text, /path/to/file нет Запись в файл
message текст нет Отправка сообщения в текущий диалог
mta текст нет Отправка сообщения всем администраторам котопая
picture URL, текст нет Отправка изображения по URL
picturedata /path/to/image, текст нет Отправка изображения по пути к файлу
resize_image /путь/к/входному/изображению, /путь/к/выхлопу, (ширина, высота) нет Изменение размера изображения

CatLib

CatENV - это не всё. Сборка Catpy может также предложить вам набор библиотек CatLib:

Название метода Входные данные Выходные данные Принадлежит библиотеке
decipher закодированные в catcipher данные результат декодирования Catware Cipher
cipher строка к примеру, test -> [/cdn-cgi/l/email-protection [email protected]]€§£@1#[/cdn-cgi/l/email-protection [email protected]]&1 Catware Cipher
getparam user_id, "названиепараметра" Содержимое параметра CUMv2 (Catware User Manager)
setparam user_id, "названиепараметра", "значение" Success или Error CUMv2
generrorcode Любая строка Генерируемый код ошибки, к примеру член члееен -> 6676676676 generrorcode
rhyme слово (str) ["олово", "говно", "хуйло", "давно", "дерьмо"] Rhymes generator
searchpic слова для поиска картинок [url1, url2, url3, url4] kalbot's ImgSearch
sget url выхлоп запроса SmartGet (представляется браузером)
transliterate текст text mlebd's transliterate

Переменные ядра и окружения системы (CoreRC, сервисы)

Переменная Примерное значение Принадлежность к Описание
osname GNU/Linux Загрузчик Семейство ОС на сервере
admins 123,123,123,123,123 Конфигурация системы Список ID вконтакте админов бота
botname CatPy Stable Конфигурация системы Имя бота
version 0.9_53 Конфигурация системы Версия бота
abms_name CatABMS | Catware Advanced Bot Manipulation System Конфигурация системы Название управляющей системы
codename Chernobyl 35y Anniversary Конфигурация системы Codename (кодовое имя выпуска)
releasedate 26.04.2021 Конфигурация системы Дата выпуска
user_id 458828641 Ядро id пользователя
peer_id 200000чётотамсколькоцифр0072 Ядро Peer ID
chat_id 72 Ядро ID чата
textic_2 /кот команды Ядро Полный текст сообщения
replytext я хуй знает Ядро Текст сообщения, на которое ответил пользователь
cmd команды Ядро Имя (триггер) использованной команды
parameter -лист Ядро Переданные параметры
argv_picture https://чётотам/чётотам.jpg Ядро URL приложенной картинки
using True/False Ядро Необходимость реагирования на команду (обработчик-оптимизатор)
serverspeed 941472 Сервис Баллы производительности системы

Введение в сервисы catABMS

Сервисы (Catware Autostart) - тупо файлы, выполняющиеся при загрузке системы и обеспечивающие работу каких либо системных аспектов, команд и так далее.

Тоже самое, но с coreRC

Core Run Commands - тупо файлы, выполняющиеся при запуске команды

Введение в CatLib

Тупо файлы с дэф-ами, чтобы не костылить в катенве. Знайте своё место блять!

Введение в catABMS Chains

Тупа новенькая фича. Итак, приступим:

Есть папка с файлами на питоне - chains. Хочу, чтобы после выполнения моей команды, юзер что то написал и файл из той папки активировался ЧИСТО У ТОГО ЮЗЕРА. Окей.

Делаем ебало:

message("Привет! Что бы ты хотел пожелать админам?")

Инициируем выполнение цепочки:

setparam(user_id, "stage", "mychainfile")

В файле цепочки, пишем код после инпута юзера:

mta(f"Привет, админы. Пользователь {getmention(user_id)} желает всем вам {textic_2}!")

И также в файле цепочки даём сигнал, что выполнение цепочки требуется прекратить:

setparam(user_id, "stage", "default")

Пример кода команды (кстати)

Конфигурация команды пусть будет:

{

"author": "Catpy Programmist <[/cdn-cgi/l/email-protection [email protected]]>",

"mode": "=",

"deps": "None",

"identificator": "ping",

"command_ru": "пинг",

"description": "Пинг бота",

"testing": false,

"hide": true,

"restricted": false,

"disabled": false

}

И код команды:

message("Понг!")

Введение в CFAT или файлы catABMS

Просто приведём таблицу:

Папка Что хранится (описание)
chains Файлы цепочек
chats БД чатов
commands Файлы с командами
configs Файлы с конфигурацией бота
corerc Файлы CoreRC
exf Файлы CatShell
experimental Тестируемые, предрелизные команды
lib Файлы с библиотеками
services Файлы Catware Autostart
users Данные пользователей (база данных)