From 511a8a3eea9a85aa6969f03fafe080116c2210b8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=91=D1=8B=D1=87=D0=BA=D0=BE=D0=B2=20=D0=90=D0=BD=D0=B4?= =?UTF-8?q?=D1=80=D0=B5=D0=B9?= Date: Fri, 13 Oct 2017 18:44:19 +0000 Subject: [PATCH] git-svn-id: svn://db.shs.com.ru/libs@297 a8b55f48-bf90-11e4-a774-851b48703e85 --- telegram_bot/execbot.cpp | 174 --------- telegram_bot/execbot.h | 47 --- telegram_bot/json.cpp | 603 ------------------------------- telegram_bot/json.h | 178 --------- telegram_bot/main.cpp | 13 - telegram_bot/telegram_bot.pro | 25 -- telegram_bot/telegrambotapi.cpp | 358 ------------------ telegram_bot/telegrambotapi.h | 119 ------ telegram_bot/telegrambotbase.cpp | 79 ---- telegram_bot/telegrambotbase.h | 54 --- 10 files changed, 1650 deletions(-) delete mode 100644 telegram_bot/execbot.cpp delete mode 100644 telegram_bot/execbot.h delete mode 100644 telegram_bot/json.cpp delete mode 100644 telegram_bot/json.h delete mode 100644 telegram_bot/main.cpp delete mode 100644 telegram_bot/telegram_bot.pro delete mode 100644 telegram_bot/telegrambotapi.cpp delete mode 100644 telegram_bot/telegrambotapi.h delete mode 100644 telegram_bot/telegrambotbase.cpp delete mode 100644 telegram_bot/telegrambotbase.h diff --git a/telegram_bot/execbot.cpp b/telegram_bot/execbot.cpp deleted file mode 100644 index 10e1bcf..0000000 --- a/telegram_bot/execbot.cpp +++ /dev/null @@ -1,174 +0,0 @@ -#include "execbot.h" -#include -#include -#include -#include -#include - -ExecBot::ExecBot(QObject *parent) : TelegramBotBase(parent) { - connect(getAPI(), SIGNAL(newFile(TelegramBotAPI::File)), this, SLOT(saveFile(TelegramBotAPI::File))); -} - - -QString ExecBot::loginMessage(uint id) { - if (sessions.contains(id)) { - if (sessions[id] == Password) return tr("Enter password"); - if (sessions[id] == NotLogged) return tr("Please send me /start"); - } - return tr("Error"); -} - - -QString ExecBot::help() { - return tr("Input command for exec on server, after exec finished result will be sended to you"); -} - - -bool ExecBot::loginUser(uint id, const QString &msg) { - if (sessions.contains(id)) { - switch (sessions[id]) { - case NotLogged: - if (msg == "/start") sessions[id] = Password; - break; - case Password: - if (msg == "rootpasswd") { - sessions[id] = Ready; - return true; - } - break; - case Ready: - case CommandExec: - return true; - default: - break; - return false; - } - } else { - if (msg == "/start") sessions[id] = Password; - else sessions[id] = NotLogged; - } - return false; -} - - -void ExecBot::messageFromUser(uint id, const QString &msg) { - if (sessions.contains(id)) { - if (msg == "/exit") { - sessions[id] = NotLogged; - disconnectUser(id); - getAPI()->sendMessage(id, tr("Logout")); - return; - } - if (sessions[id] == CommandExec) { - if (msg == "/kill") { - int rm = -1; - for (int i=0; iterminate(); - getAPI()->sendMessage(id, tr("Process killed")); - sessions[id] = Ready; - rm = i; - } - } - if (rm >= 0) { - run_commands[rm].cmd->deleteLater(); - run_commands.remove(rm); - } - } else - getAPI()->sendMessage(id, tr("Command is running, please wait for finish")); - return; - } - if (sessions[id] == Ready) { - if (msg.startsWith("/download")) { - QFile f; - f.setFileName(msg.mid(9).trimmed()); - if (f.open(QIODevice::ReadOnly)) { - QByteArray ba = f.readAll(); - getAPI()->sendMessage(id, TelegramBotAPI::Document, ba, QFileInfo(f).fileName()); - } else - getAPI()->sendMessage(id, tr("File not found")); - return; - } - getAPI()->sendMessage(id, "exec: " + msg); - UserCommand uc; - uc.user = id; - uc.cmd = new QProcess(); -// uc.cmd->setProcessChannelMode(QProcess::MergedChannels); - connect(uc.cmd, SIGNAL(readyRead()), this, SLOT(cmdRead())); -// connect(uc.cmd, SIGNAL(started()), this, SLOT(cmdStart())); - connect(uc.cmd, SIGNAL(finished(int)), this, SLOT(cmdFinish(int))); - uc.cmd->start(msg); - if (uc.cmd->waitForStarted(3000)) { - sessions[id] = CommandExec; - run_commands.append(uc); - } else getAPI()->sendMessage(id, tr("Can't run command %1").arg(msg)); - } - } -} - - -void ExecBot::cmdRead() { -// qDebug() << "cmdRead()"; - QProcess * p = (QProcess *)sender(); - for (int i=0; itoUnicode(p->readAll()); - getAPI()->sendMessage(id, s); - } - } -} - -void ExecBot::cmdFinish(int code) { -// qDebug() << "cmdFinish()" << code; - QProcess * p = (QProcess *)sender(); - int rm = -1; - for (int i=0; itoUnicode(p->readAll()); - getAPI()->sendMessage(id, s); - rm = i; - sessions[id] = Ready; - } - } - if (rm >= 0) { - run_commands[rm].cmd->deleteLater(); - getAPI()->sendMessage(run_commands[rm].user, tr("Command finished with code %1").arg(code)); - run_commands.remove(rm); - } -} - - -void ExecBot::saveFile(TelegramBotAPI::File fl) { - if (sessions.contains(fl.chat_id)) { - if (sessions[fl.chat_id] == Ready) { - QFile f; - QDir::current().mkdir("uploads"); - f.setFileName("uploads/" + fl.filename); - if (f.open(QIODevice::ReadWrite)) { - f.resize(0); - f.write(fl.data); - getAPI()->sendMessage(fl.chat_id, tr("File received")); - } else { - getAPI()->sendMessage(fl.chat_id, tr("Can't write file")); - } - } else { - getAPI()->sendMessage(fl.chat_id, loginMessage(fl.chat_id)); - } - } else { - getAPI()->sendMessage(fl.chat_id, tr("Please send me /start")); - } -} - - diff --git a/telegram_bot/execbot.h b/telegram_bot/execbot.h deleted file mode 100644 index 5c80667..0000000 --- a/telegram_bot/execbot.h +++ /dev/null @@ -1,47 +0,0 @@ -#ifndef EXECBOT_H -#define EXECBOT_H - -#include "telegrambotbase.h" -#include - - -class ExecBot : public TelegramBotBase -{ - Q_OBJECT -public: - explicit ExecBot(QObject *parent = 0); - - -public slots: - -private: - enum UserState { - NotLogged, - Password, - Ready, - CommandExec - }; - struct UserCommand { - uint user; - QProcess * cmd; - }; - - virtual QString loginMessage(uint id); - virtual QString help(); - virtual bool loginUser(uint id, const QString & msg); - virtual void messageFromUser(uint id, const QString & msg); - void runCMD(UserCommand uc); - - QMap sessions; - QVector run_commands; - -private slots: - void cmdRead(); - void cmdFinish(int code); - void saveFile(TelegramBotAPI::File fl); - -signals: - -}; - -#endif // EXECBOT_H diff --git a/telegram_bot/json.cpp b/telegram_bot/json.cpp deleted file mode 100644 index 1aa505b..0000000 --- a/telegram_bot/json.cpp +++ /dev/null @@ -1,603 +0,0 @@ -/** - * QtJson - A simple class for parsing JSON data into a QVariant hierarchies and vice-versa. - * Copyright (C) 2011 Eeli Reilin - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -/** - * \file json.cpp - */ - -#include -#include -#include "json.h" - -namespace QtJson { - static QString dateFormat, dateTimeFormat; - - static QString sanitizeString(QString str); - static QByteArray join(const QList &list, const QByteArray &sep); - static QVariant parseValue(const QString &json, int &index, bool &success); - static QVariant parseObject(const QString &json, int &index, bool &success); - static QVariant parseArray(const QString &json, int &index, bool &success); - static QVariant parseString(const QString &json, int &index, bool &success); - static QVariant parseNumber(const QString &json, int &index); - static int lastIndexOfNumber(const QString &json, int index); - static void eatWhitespace(const QString &json, int &index); - static int lookAhead(const QString &json, int index); - static int nextToken(const QString &json, int &index); - - template - QByteArray serializeMap(const T &map, bool &success) { - QByteArray str = "{ "; - QList pairs; - for (typename T::const_iterator it = map.begin(), itend = map.end(); it != itend; ++it) { - QByteArray serializedValue = serialize(it.value()); - if (serializedValue.isNull()) { - success = false; - break; - } - pairs << sanitizeString(it.key()).toUtf8() + " : " + serializedValue; - } - - str += join(pairs, ", "); - str += " }"; - return str; - } - - void insert(QVariant &v, const QString &key, const QVariant &value); - void append(QVariant &v, const QVariant &value); - - template - void cloneMap(QVariant &json, const T &map) { - for (typename T::const_iterator it = map.begin(), itend = map.end(); it != itend; ++it) { - insert(json, it.key(), (*it)); - } - } - - template - void cloneList(QVariant &json, const T &list) { - for (typename T::const_iterator it = list.begin(), itend = list.end(); it != itend; ++it) { - append(json, (*it)); - } - } - - /** - * parse - */ - QVariant parse(const QString &json) { - bool success = true; - return parse(json, success); - } - - /** - * parse - */ - QVariant parse(const QString &json, bool &success) { - success = true; - - // Return an empty QVariant if the JSON data is either null or empty - if (!json.isNull() || !json.isEmpty()) { - QString data = json; - // We'll start from index 0 - int index = 0; - - // Parse the first value - QVariant value = parseValue(data, index, success); - - // Return the parsed value - return value; - } else { - // Return the empty QVariant - return QVariant(); - } - } - - /** - * clone - */ - QVariant clone(const QVariant &data) { - QVariant v; - - if (data.type() == QVariant::Map) { - cloneMap(v, data.toMap()); - } else if (data.type() == QVariant::Hash) { - cloneMap(v, data.toHash()); - } else if (data.type() == QVariant::List) { - cloneList(v, data.toList()); - } else if (data.type() == QVariant::StringList) { - cloneList(v, data.toStringList()); - } else { - v = QVariant(data); - } - - return v; - } - - /** - * insert value (map case) - */ - void insert(QVariant &v, const QString &key, const QVariant &value) { - if (!v.canConvert()) v = QVariantMap(); - QVariantMap *p = (QVariantMap *)v.data(); - p->insert(key, clone(value)); - } - - /** - * append value (list case) - */ - void append(QVariant &v, const QVariant &value) { - if (!v.canConvert()) v = QVariantList(); - QVariantList *p = (QVariantList *)v.data(); - p->append(value); - } - - QByteArray serialize(const QVariant &data) { - bool success = true; - return serialize(data, success); - } - - QByteArray serialize(const QVariant &data, bool &success) { - QByteArray str; - success = true; - - if (!data.isValid()) { // invalid or null? - str = "null"; - } else if ((data.type() == QVariant::List) || - (data.type() == QVariant::StringList)) { // variant is a list? - QList values; - const QVariantList list = data.toList(); - Q_FOREACH(const QVariant& v, list) { - QByteArray serializedValue = serialize(v); - if (serializedValue.isNull()) { - success = false; - break; - } - values << serializedValue; - } - - str = "[ " + join( values, ", " ) + " ]"; - } else if (data.type() == QVariant::Hash) { // variant is a hash? - str = serializeMap<>(data.toHash(), success); - } else if (data.type() == QVariant::Map) { // variant is a map? - str = serializeMap<>(data.toMap(), success); - } else if ((data.type() == QVariant::String) || - (data.type() == QVariant::ByteArray)) {// a string or a byte array? - str = sanitizeString(data.toString()).toUtf8(); - } else if (data.type() == QVariant::Double) { // double? - double value = data.toDouble(&success); - if (success) { - str = QByteArray::number(value, 'g'); - if (!str.contains(".") && ! str.contains("e")) { - str += ".0"; - } - } - } else if (data.type() == QVariant::Bool) { // boolean value? - str = data.toBool() ? "true" : "false"; - } else if (data.type() == QVariant::ULongLong) { // large unsigned number? - str = QByteArray::number(data.value()); - } else if (data.canConvert()) { // any signed number? - str = QByteArray::number(data.value()); - } else if (data.canConvert()) { //TODO: this code is never executed because all smaller types can be converted to qlonglong - str = QString::number(data.value()).toUtf8(); - } else if (data.type() == QVariant::DateTime) { // datetime value? - str = sanitizeString(dateTimeFormat.isEmpty() - ? data.toDateTime().toString() - : data.toDateTime().toString(dateTimeFormat)).toUtf8(); - } else if (data.type() == QVariant::Date) { // date value? - str = sanitizeString(dateTimeFormat.isEmpty() - ? data.toDate().toString() - : data.toDate().toString(dateFormat)).toUtf8(); - } else if (data.canConvert()) { // can value be converted to string? - // this will catch QUrl, ... (all other types which can be converted to string) - str = sanitizeString(data.toString()).toUtf8(); - } else { - success = false; - } - - if (success) { - return str; - } - return QByteArray(); - } - - QString serializeStr(const QVariant &data) { - return QString::fromUtf8(serialize(data)); - } - - QString serializeStr(const QVariant &data, bool &success) { - return QString::fromUtf8(serialize(data, success)); - } - - - /** - * \enum JsonToken - */ - enum JsonToken { - JsonTokenNone = 0, - JsonTokenCurlyOpen = 1, - JsonTokenCurlyClose = 2, - JsonTokenSquaredOpen = 3, - JsonTokenSquaredClose = 4, - JsonTokenColon = 5, - JsonTokenComma = 6, - JsonTokenString = 7, - JsonTokenNumber = 8, - JsonTokenTrue = 9, - JsonTokenFalse = 10, - JsonTokenNull = 11 - }; - - static QString sanitizeString(QString str) { - str.replace(QLatin1String("\\"), QLatin1String("\\\\")); - str.replace(QLatin1String("\""), QLatin1String("\\\"")); - str.replace(QLatin1String("\b"), QLatin1String("\\b")); - str.replace(QLatin1String("\f"), QLatin1String("\\f")); - str.replace(QLatin1String("\n"), QLatin1String("\\n")); - str.replace(QLatin1String("\r"), QLatin1String("\\r")); - str.replace(QLatin1String("\t"), QLatin1String("\\t")); - return QString(QLatin1String("\"%1\"")).arg(str); - } - - static QByteArray join(const QList &list, const QByteArray &sep) { - QByteArray res; - Q_FOREACH(const QByteArray &i, list) { - if (!res.isEmpty()) { - res += sep; - } - res += i; - } - return res; - } - - /** - * parseValue - */ - static QVariant parseValue(const QString &json, int &index, bool &success) { - // Determine what kind of data we should parse by - // checking out the upcoming token - switch(lookAhead(json, index)) { - case JsonTokenString: - return parseString(json, index, success); - case JsonTokenNumber: - return parseNumber(json, index); - case JsonTokenCurlyOpen: - return parseObject(json, index, success); - case JsonTokenSquaredOpen: - return parseArray(json, index, success); - case JsonTokenTrue: - nextToken(json, index); - return QVariant(true); - case JsonTokenFalse: - nextToken(json, index); - return QVariant(false); - case JsonTokenNull: - nextToken(json, index); - return QVariant(); - case JsonTokenNone: - break; - } - - // If there were no tokens, flag the failure and return an empty QVariant - success = false; - return QVariant(); - } - - /** - * parseObject - */ - static QVariant parseObject(const QString &json, int &index, bool &success) { - QVariantMap map; - int token; - - // Get rid of the whitespace and increment index - nextToken(json, index); - - // Loop through all of the key/value pairs of the object - bool done = false; - while (!done) { - // Get the upcoming token - token = lookAhead(json, index); - - if (token == JsonTokenNone) { - success = false; - return QVariantMap(); - } else if (token == JsonTokenComma) { - nextToken(json, index); - } else if (token == JsonTokenCurlyClose) { - nextToken(json, index); - return map; - } else { - // Parse the key/value pair's name - QString name = parseString(json, index, success).toString(); - - if (!success) { - return QVariantMap(); - } - - // Get the next token - token = nextToken(json, index); - - // If the next token is not a colon, flag the failure - // return an empty QVariant - if (token != JsonTokenColon) { - success = false; - return QVariant(QVariantMap()); - } - - // Parse the key/value pair's value - QVariant value = parseValue(json, index, success); - - if (!success) { - return QVariantMap(); - } - - // Assign the value to the key in the map - map[name] = value; - } - } - - // Return the map successfully - return QVariant(map); - } - - /** - * parseArray - */ - static QVariant parseArray(const QString &json, int &index, bool &success) { - QVariantList list; - - nextToken(json, index); - - bool done = false; - while(!done) { - int token = lookAhead(json, index); - - if (token == JsonTokenNone) { - success = false; - return QVariantList(); - } else if (token == JsonTokenComma) { - nextToken(json, index); - } else if (token == JsonTokenSquaredClose) { - nextToken(json, index); - break; - } else { - QVariant value = parseValue(json, index, success); - if (!success) { - return QVariantList(); - } - list.push_back(value); - } - } - - return QVariant(list); - } - - /** - * parseString - */ - static QVariant parseString(const QString &json, int &index, bool &success) { - QString s; - QChar c; - - eatWhitespace(json, index); - - c = json[index++]; - - bool complete = false; - while(!complete) { - if (index == json.size()) { - break; - } - - c = json[index++]; - - if (c == '\"') { - complete = true; - break; - } else if (c == '\\') { - if (index == json.size()) { - break; - } - - c = json[index++]; - - if (c == '\"') { - s.append('\"'); - } else if (c == '\\') { - s.append('\\'); - } else if (c == '/') { - s.append('/'); - } else if (c == 'b') { - s.append('\b'); - } else if (c == 'f') { - s.append('\f'); - } else if (c == 'n') { - s.append('\n'); - } else if (c == 'r') { - s.append('\r'); - } else if (c == 't') { - s.append('\t'); - } else if (c == 'u') { - int remainingLength = json.size() - index; - if (remainingLength >= 4) { - QString unicodeStr = json.mid(index, 4); - - int symbol = unicodeStr.toInt(0, 16); - - s.append(QChar(symbol)); - - index += 4; - } else { - break; - } - } - } else { - s.append(c); - } - } - - if (!complete) { - success = false; - return QVariant(); - } - - return QVariant(s); - } - - /** - * parseNumber - */ - static QVariant parseNumber(const QString &json, int &index) { - eatWhitespace(json, index); - - int lastIndex = lastIndexOfNumber(json, index); - int charLength = (lastIndex - index) + 1; - QString numberStr; - - numberStr = json.mid(index, charLength); - - index = lastIndex + 1; - bool ok; - - if (numberStr.contains('.')) { - return QVariant(numberStr.toDouble(NULL)); - } else if (numberStr.startsWith('-')) { - int i = numberStr.toInt(&ok); - if (!ok) { - qlonglong ll = numberStr.toLongLong(&ok); - return ok ? ll : QVariant(numberStr); - } - return i; - } else { - uint u = numberStr.toUInt(&ok); - if (!ok) { - qulonglong ull = numberStr.toULongLong(&ok); - return ok ? ull : QVariant(numberStr); - } - return u; - } - } - - /** - * lastIndexOfNumber - */ - static int lastIndexOfNumber(const QString &json, int index) { - int lastIndex; - - for(lastIndex = index; lastIndex < json.size(); lastIndex++) { - if (QString("0123456789+-.eE").indexOf(json[lastIndex]) == -1) { - break; - } - } - - return lastIndex -1; - } - - /** - * eatWhitespace - */ - static void eatWhitespace(const QString &json, int &index) { - for(; index < json.size(); index++) { - if (QString(" \t\n\r").indexOf(json[index]) == -1) { - break; - } - } - } - - /** - * lookAhead - */ - static int lookAhead(const QString &json, int index) { - int saveIndex = index; - return nextToken(json, saveIndex); - } - - /** - * nextToken - */ - static int nextToken(const QString &json, int &index) { - eatWhitespace(json, index); - - if (index == json.size()) { - return JsonTokenNone; - } - - QChar c = json[index]; - index++; - switch(c.toLatin1()) { - case '{': return JsonTokenCurlyOpen; - case '}': return JsonTokenCurlyClose; - case '[': return JsonTokenSquaredOpen; - case ']': return JsonTokenSquaredClose; - case ',': return JsonTokenComma; - case '"': return JsonTokenString; - case '0': case '1': case '2': case '3': case '4': - case '5': case '6': case '7': case '8': case '9': - case '-': return JsonTokenNumber; - case ':': return JsonTokenColon; - } - index--; // ^ WTF? - - int remainingLength = json.size() - index; - - // True - if (remainingLength >= 4) { - if (json[index] == 't' && json[index + 1] == 'r' && - json[index + 2] == 'u' && json[index + 3] == 'e') { - index += 4; - return JsonTokenTrue; - } - } - - // False - if (remainingLength >= 5) { - if (json[index] == 'f' && json[index + 1] == 'a' && - json[index + 2] == 'l' && json[index + 3] == 's' && - json[index + 4] == 'e') { - index += 5; - return JsonTokenFalse; - } - } - - // Null - if (remainingLength >= 4) { - if (json[index] == 'n' && json[index + 1] == 'u' && - json[index + 2] == 'l' && json[index + 3] == 'l') { - index += 4; - return JsonTokenNull; - } - } - - return JsonTokenNone; - } - - void setDateTimeFormat(const QString &format) { - dateTimeFormat = format; - } - - void setDateFormat(const QString &format) { - dateFormat = format; - } - - QString getDateTimeFormat() { - return dateTimeFormat; - } - - QString getDateFormat() { - return dateFormat; - } - -} //end namespace diff --git a/telegram_bot/json.h b/telegram_bot/json.h deleted file mode 100644 index 8992508..0000000 --- a/telegram_bot/json.h +++ /dev/null @@ -1,178 +0,0 @@ -/** - * QtJson - A simple class for parsing JSON data into a QVariant hierarchies and vice-versa. - * Copyright (C) 2011 Eeli Reilin - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -/** - * \file json.h - */ - -#ifndef JSON_H -#define JSON_H - -#include -#include - - -/** - * \namespace QtJson - * \brief A JSON data parser - * - * Json parses a JSON data into a QVariant hierarchy. - */ -namespace QtJson { - typedef QVariantMap JsonObject; - typedef QVariantList JsonArray; - - /** - * Clone a JSON object (makes a deep copy) - * - * \param data The JSON object - */ - QVariant clone(const QVariant &data); - - /** - * Insert value to JSON object (QVariantMap) - * - * \param v The JSON object - * \param key The key - * \param value The value - */ - void insert(QVariant &v, const QString &key, const QVariant &value); - - /** - * Append value to JSON array (QVariantList) - * - * \param v The JSON array - * \param value The value - */ - void append(QVariant &v, const QVariant &value); - - /** - * Parse a JSON string - * - * \param json The JSON data - */ - QVariant parse(const QString &json); - - /** - * Parse a JSON string - * - * \param json The JSON data - * \param success The success of the parsing - */ - QVariant parse(const QString &json, bool &success); - - /** - * This method generates a textual JSON representation - * - * \param data The JSON data generated by the parser. - * - * \return QByteArray Textual JSON representation in UTF-8 - */ - QByteArray serialize(const QVariant &data); - - /** - * This method generates a textual JSON representation - * - * \param data The JSON data generated by the parser. - * \param success The success of the serialization - * - * \return QByteArray Textual JSON representation in UTF-8 - */ - QByteArray serialize(const QVariant &data, bool &success); - - /** - * This method generates a textual JSON representation - * - * \param data The JSON data generated by the parser. - * - * \return QString Textual JSON representation - */ - QString serializeStr(const QVariant &data); - - /** - * This method generates a textual JSON representation - * - * \param data The JSON data generated by the parser. - * \param success The success of the serialization - * - * \return QString Textual JSON representation - */ - QString serializeStr(const QVariant &data, bool &success); - - /** - * This method sets date(time) format to be used for QDateTime::toString - * If QString is empty, Qt::TextDate is used. - * - * \param format The JSON data generated by the parser. - */ - void setDateTimeFormat(const QString& format); - void setDateFormat(const QString& format); - - /** - * This method gets date(time) format to be used for QDateTime::toString - * If QString is empty, Qt::TextDate is used. - */ - QString getDateTimeFormat(); - QString getDateFormat(); - - /** - * QVariant based Json object - */ - class Object : public QVariant { - template - Object& insertKey(Object* ptr, const QString& key) { - T* p = (T*)ptr->data(); - if (!p->contains(key)) p->insert(key, QVariant()); - return *reinterpret_cast(&p->operator[](key)); - } - template - void removeKey(Object *ptr, const QString& key) { - T* p = (T*)ptr->data(); - p->remove(key); - } - public: - Object() : QVariant() {} - Object(const Object& ref) : QVariant(ref) {} - - Object& operator=(const QVariant& rhs) { - setValue(rhs); - return *this; - } - Object& operator[](const QString& key) { - if (type() == QVariant::Map) - return insertKey(this, key); - else if (type() == QVariant::Hash) - return insertKey(this, key); - - setValue(QVariantMap()); - - return insertKey(this, key); - } - const Object& operator[](const QString& key) const { - return const_cast(this)->operator[](key); - } - void remove(const QString& key) { - if (type() == QVariant::Map) - removeKey(this, key); - else if (type() == QVariant::Hash) - removeKey(this, key); - } - }; -} - -#endif //JSON_H diff --git a/telegram_bot/main.cpp b/telegram_bot/main.cpp deleted file mode 100644 index 033a1c3..0000000 --- a/telegram_bot/main.cpp +++ /dev/null @@ -1,13 +0,0 @@ -//#include "mainwindow.h" -#include "execbot.h" -#include - -int main(int argc, char *argv[]) -{ - QCoreApplication a(argc, argv); - //MainWindow w; - //w.show(); - ExecBot bot; - bot.setBotToken("242608352:AAFrx51P_JhmCjV8CV11Mds-LJk89bpolXE"); - return a.exec(); -} diff --git a/telegram_bot/telegram_bot.pro b/telegram_bot/telegram_bot.pro deleted file mode 100644 index d7ed823..0000000 --- a/telegram_bot/telegram_bot.pro +++ /dev/null @@ -1,25 +0,0 @@ -#------------------------------------------------- -# -# Project created by QtCreator 2016-10-17T12:59:23 -# -#------------------------------------------------- - -QT += core gui network - -TARGET = telegram_bot -TEMPLATE = app - - -SOURCES += main.cpp\ - json.cpp \ - telegrambotapi.cpp \ - telegrambotbase.cpp \ - execbot.cpp - -HEADERS += \ - json.h \ - telegrambotapi.h \ - telegrambotbase.h \ - execbot.h - -FORMS += diff --git a/telegram_bot/telegrambotapi.cpp b/telegram_bot/telegrambotapi.cpp deleted file mode 100644 index e4861dd..0000000 --- a/telegram_bot/telegrambotapi.cpp +++ /dev/null @@ -1,358 +0,0 @@ -#include "telegrambotapi.h" -//#include -#include -#include -#include -#include -#include -#include "json.h" - - -const char * TelegramBotAPI::send_methods[] = { - "sendMessage", - "sendPhoto", - "sendDocument", - }; -const char * TelegramBotAPI::param_filename = "__filename"; - -TelegramBotAPI::TelegramBotAPI(QObject *parent) : QObject(parent) { - is_connected = false; - wait_server = false; - has_stop = false; - qRegisterMetaType("TelegramBotAPI::Message"); - qnam = new QNetworkAccessManager(); -// connect(qnam, SIGNAL(finished(QNetworkReply*)), this, SLOT(httpFinished(QNetworkReply*))); - connect(qnam, SIGNAL(sslErrors(QNetworkReply*,QList)), this, SLOT(sslErrors(QNetworkReply*,QList))); -} - - - TelegramBotAPI::~TelegramBotAPI() { - has_stop = true; -// msleep(60); -} - - -void TelegramBotAPI::setBotToken(QString arg) { - if (m_botToken == arg) { - checkBot(); - return; - } - is_connected = false; - m_botToken = arg; - botUrl = "https://api.telegram.org/bot"+m_botToken+"/"; - checkBot(); -} - - -bool TelegramBotAPI::sendMessage(uint chat_id, TelegramBotAPI::MessageType mtype, QByteArray data, QString filename) { - if (!is_connected || chat_id == 0 || data.isEmpty()) return false; - SendQuery sq; - sq.params["chat_id"] = chat_id; - sq.method = send_methods[mtype]; - bool ok = false; - switch (mtype) { - case Text: - sq.params["text"] = QString::fromUtf8(data.data(), data.size()); - ok = true; - break; - case Photo: - if (!filename.isEmpty()) { - sq.params[param_filename] = filename; - sq.params["photo"] = data; - ok = true; - } - break; - case Document: - if (!filename.isEmpty()) { - sq.params[param_filename] = filename; - sq.params["document"] = data; - ok = true; - } - break; - default: - break; - } - if (ok) { - sendmsg_que.enqueue(sq); - if (wait_server) { - if (reply->url().toString().split("/").last() == "getUpdates") reply->abort(); - } - } - return ok; -} - - -//void TelegramBot::run() { -// while (!has_stop) { -// mutex.lock(); -// if (qnam == 0) { -// qnam = new QNetworkAccessManager(); -// connect(qnam, SIGNAL(finished(QNetworkReply*)), -// this, SLOT(httpFinished(QNetworkReply*))); -// connect(qnam, SIGNAL(sslErrors(QNetworkReply*,QList)), this, SLOT(sslErrors(QNetworkReply*,QList))); -// } -// if (!wait_server) { -// if (!is_connected) checkBot(); -// updateBot(); -// } -// mutex.unlock(); -// msleep(50); -// } -//} - - -void TelegramBotAPI::updateBot() { - if (!is_connected) return; - QVariantMap vm; - vm["timeout"] = 50; - vm["offset"] = last_update; - sendRequest("getUpdates", vm); -} - - -bool TelegramBotAPI::fileDownload() { - if (download_list.isEmpty()) return false; - bool ok = false; - int rm = -1; - for(int i=0; iget(nr); - connect(reply, SIGNAL(finished()), this, SLOT(httpFinished())); - return true; - } else { - File f; - f.chat_id = df.chat_id; - f.filename = df.filename; - f.data = df.data; - emit newFile(f); - rm = i; - break; - } - } - } - if (rm >= 0) download_list.removeAt(rm); - return ok; -} - - -void TelegramBotAPI::checkBot() { - sendRequest("getMe", QVariantMap()); -} - - -bool TelegramBotAPI::parseHeader(QString json, QVariant & res) { - bool ok; - QVariantMap map = QtJson::parse(json, ok).toMap(); - if (!ok) { - emit errorOccured("parse JSON error"); - return false; - } - if (!map.value("ok").toBool()) { - emit errorOccured("query error"); - return false; - } - res = map.value("result"); - return !res.isNull() && res.isValid(); -} - - -void TelegramBotAPI::parseCheckBot(QString json) { - QVariant res; - if (!parseHeader(json, res)) { - is_connected = false; - emit botFail(); - return; - } - QVariantMap resm = res.toMap(); - m_botID = resm.value("id").toUInt(); - m_botName = resm.value("username").toString(); - is_connected = true; - last_update = 0; - emit botOK(); -} - - -void TelegramBotAPI::parseFile(QString json) { - QVariant res; - if (!parseHeader(json, res)) { - emit errorOccured("can't get file"); - return; - } - QVariantMap resm = res.toMap(); - QString fpath = resm["file_path"].toString(); - QString fid = resm["file_id"].toString(); - if (fpath.isEmpty()) return; - QUrl furl = QUrl("https://api.telegram.org/file/bot"+m_botToken+"/"+fpath); - qDebug() << "new file :" << furl; - for (int i=0; i 0 && !m.text.isEmpty()) { - emit newMessage(m); - emit newMessage(m.chat_id, m.text); - } - } - last_update++; - //qDebug() << "update_id" << last_update; -} - - -void TelegramBotAPI::startDownloadFile(uint chat_id, QVariantMap file) { - if (!file.isEmpty()) { - DownloadFile df; - df.downloaded = false; - df.id = file["file_id"].toString(); - df.chat_id = chat_id; - df.filename = file["file_name"].toString(); - qDebug() << "new incomming file" << df.id; - download_list << df; - } -} - - -TelegramBotAPI::Message TelegramBotAPI::parseMessage(QVariant msg) { - Message ret; - QVariantMap map = msg.toMap(); - ret.id = map.value("message_id", 0).toUInt(); - QVariantMap chat = map.value("chat").toMap(); - ret.chat_id = chat.value("id", 0).toUInt(); - QVariantMap user = map.value("from").toMap(); - ret.user_id = user.value("id", 0).toUInt(); - ret.user_name = user.value("first_name").toString(); - ret.text = map.value("text").toString(); - ret.time = QDateTime::fromTime_t(map.value("date").toUInt()); - QVariantMap file; - QVariantList photo = map.value("photo").toList(); - if (!photo.isEmpty()) { - startDownloadFile(ret.chat_id, photo.last().toMap()); - } - QVariantMap docum = map.value("document").toMap(); - startDownloadFile(ret.chat_id, docum); - return ret; -} - - -void TelegramBotAPI::sslErrors(QNetworkReply*,const QList &errors) { - QString errorString; - foreach (const QSslError &error, errors) { - if (!errorString.isEmpty()) - errorString += ", "; - errorString += error.errorString(); - } - emit errorOccured(errorString); -// if (QMessageBox::warning(0, QString("HTTP"), QString("One or more SSL errors has occurred: %1").arg(errorString), -// QMessageBox::Ignore | QMessageBox::Abort, QMessageBox::Ignore) -// == QMessageBox::Ignore) { -// reply->ignoreSslErrors(); -// } -} - - -void TelegramBotAPI::httpFinished() { -// qDebug() << "reply finished"; -// mutex.lock(); - QByteArray ba = reply->readAll(); - QStringList quest_path = reply->url().toString().split("/"); -// qDebug() << "quest list =" << quest_path.size(); - QString quest = quest_path.last(); - reply->deleteLater(); - wait_server = false; -// mutex.unlock(); - if (quest_path.size() == 5) { - QString s = QString::fromUtf8(ba.data(), ba.size()); - // qDebug() << quest << s; - // if (quest.indexOf("?") > 0) - // quest.resize(quest.indexOf('?')); - QVariant tmp; - if (quest == "getMe") parseCheckBot(s); - if (quest == "getFile") parseFile(s); - if (quest == "getUpdates") parseMessages(s); - if (quest == "sendMessage") parseHeader(s, tmp); - qDebug() << "parse done" << quest << s; - } else { - for (int i=0; iurl()) { - download_list[i].data = ba; - download_list[i].downloaded = true; - break; - } - } - } - if (is_connected) { - if (!fileDownload()) { - if (sendmsg_que.isEmpty()) updateBot(); - else { - SendQuery sq = sendmsg_que.dequeue(); - sendRequest(sq.method, sq.params); - } - } - } else checkBot(); -} - - -//void TelegramBot::httpFinished(QNetworkReply *) { -// qDebug() << "get finished"; -//} - - -void TelegramBotAPI::sendRequest(QString method, QVariantMap params) { - wait_server = true; - qDebug() << "startRequest:" << method; - QHttpMultiPart *multiPart = new QHttpMultiPart(QHttpMultiPart::FormDataType); - - QString filename = params.take(param_filename).toString(); - QMapIterator it(params); - while (it.hasNext()) { - it.next(); - QHttpPart part; - if (it.value().type() == QVariant::ByteArray) { - part.setHeader(QNetworkRequest::ContentDispositionHeader, QVariant("form-data; filename=\""+filename+"\"; name=\""+it.key()+"\"")); - qDebug() << "sending file" << double(it.value().toByteArray().size()) / (1024*1024) << "Mb"; - part.setBody(it.value().toByteArray()); - } else { - part.setHeader(QNetworkRequest::ContentDispositionHeader, QVariant("form-data; name=\""+it.key()+"\"")); - part.setBody(it.value().toString().toUtf8()); - } - multiPart->append(part); - } - if (params.isEmpty()) { - QHttpPart part; - part.setHeader(QNetworkRequest::ContentDispositionHeader, QVariant("form-data; name=\"text\"")); - multiPart->append(part); - } - QNetworkRequest nr; - nr.setUrl(QUrl(botUrl + method)); - reply = qnam->post(nr, multiPart); - multiPart->setParent(reply); // delete the multiPart with the reply - connect(reply, SIGNAL(finished()), this, SLOT(httpFinished())); -// connect(reply, SIGNAL(readyRead()), this, SLOT(httpReadyRead())); -// connect(reply, SIGNAL(downloadProgress(qint64,qint64)), this, SLOT(updateDataReadProgress(qint64,qint64))); -} diff --git a/telegram_bot/telegrambotapi.h b/telegram_bot/telegrambotapi.h deleted file mode 100644 index 055d850..0000000 --- a/telegram_bot/telegrambotapi.h +++ /dev/null @@ -1,119 +0,0 @@ -#ifndef TELEGRAMBOTAPI_H -#define TELEGRAMBOTAPI_H - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -class TelegramBotAPI : public QObject -{ - Q_OBJECT - Q_PROPERTY(uint botID READ botID) - Q_PROPERTY(QString botName READ botName) - Q_PROPERTY(QString botToken READ botToken WRITE setBotToken) -public: - explicit TelegramBotAPI(QObject *parent = 0); - ~TelegramBotAPI(); - - enum MessageType { - Text, - Photo, - Document, - }; - - struct Message { - Message() { - chat_id = id = user_id = 0; - } - uint id; - uint chat_id; - uint user_id; - QString user_name; - QString text; - QDateTime time; - }; - struct File { - uint chat_id; - QString filename; - QByteArray data; - }; - - uint botID() const {return m_botID;} - QString botToken() const {return m_botToken;} - QString botName() const {return m_botName;} - bool isConnected() const {return is_connected;} - -public slots: - void setBotToken(QString arg); - bool sendMessage(uint chat_id, QString msg) {return sendMessage(chat_id, TelegramBotAPI::Text, msg.toUtf8());} - bool sendMessage(uint chat_id, MessageType mtype, QByteArray data, QString filename = QString()); - -private: - - struct SendQuery { - QString method; - QVariantMap params; - }; - - struct DownloadFile { - bool downloaded; - int chat_id; - QString id; - QString filename; - QUrl url; - QByteArray data; - }; - - static const char * send_methods[]; - static const char * param_filename; - -// void run(); - void sendRequest(QString method, QVariantMap params); - void checkBot(); - void updateBot(); - bool fileDownload(); - bool parseHeader(QString json, QVariant &res); - void parseCheckBot(QString json); - void parseMessages(QString json); - void parseFile(QString json); - Message parseMessage(QVariant msg); - void startDownloadFile(uint chat_id, QVariantMap file); - - QNetworkAccessManager * qnam; - QNetworkReply *reply; -// QMutex mutex; - uint m_botID; - QString m_botToken; - QString botUrl; - QString botUrlFile; - QString m_botName; - bool is_connected; - int last_update; - bool wait_server; - bool has_stop; - QQueue sendmsg_que; - QList download_list; - -private slots: - void sslErrors(QNetworkReply*, const QList &errors); - void httpFinished(); -// void httpFinished(QNetworkReply*); - -signals: - void botOK(); - void botFail(); - void errorOccured(QString error); - void newMessage(TelegramBotAPI::Message msg); - void newMessage(uint chat_id, QString msg); - void newFile(TelegramBotAPI::File file); -}; - -Q_DECLARE_METATYPE(TelegramBotAPI::Message) - -#endif // TELEGRAMBOTAPI_H diff --git a/telegram_bot/telegrambotbase.cpp b/telegram_bot/telegrambotbase.cpp deleted file mode 100644 index bf7da80..0000000 --- a/telegram_bot/telegrambotbase.cpp +++ /dev/null @@ -1,79 +0,0 @@ -#include "telegrambotbase.h" -#include -#include - -TelegramBotBase::TelegramBotBase(QObject *parent) : QObject(parent) { -// connect(&api, SIGNAL(newMessage(TelegramBotAPI::Message)), this, SLOT(processMessage(TelegramBotAPI::Message)), Qt::QueuedConnection); - connect(&api, SIGNAL(newMessage(TelegramBotAPI::Message)), this, SLOT(processMessage(TelegramBotAPI::Message))); -} - - -void TelegramBotBase::sendMessageToAll(const QString &message) { - QList keys = users.keys(); - foreach (uint cid, keys) { - if (users[cid].logged_in) - api.sendMessage(cid, message); - } -} - - -void TelegramBotBase::processMessage(TelegramBotAPI::Message msg) { -// QApplication::processEvents(); - qDebug() << "[TelegramBotBase]" << msg.text; - uint cid = msg.chat_id; - User m; - m.user_id = msg.user_id; - m.user_name = msg.user_name; - m.last_timestamp = msg.time; - if (!users.contains(cid)) users[cid] = m; - if (users[cid].logged_in) { - if (msg.text == "/help") { - api.sendMessage(cid, help()); - return; - } - messageFromUser(cid, msg.text); - } else { - if (loginUser(cid, msg.text)) { - users[cid].logged_in = true; - api.sendMessage(cid, welcome(cid)); - newUser(cid, users[cid]); - } else { - api.sendMessage(cid, loginMessage(cid)); - } - return; - } -} - - -QString TelegramBotBase::welcome(uint id) { - User user = getUser(id); - return tr("Hello %1! I am @%2.").arg(user.user_name).arg(api.botName()); -} - - -QString TelegramBotBase::loginMessage(uint) { - return tr("Please send me /start"); -} - - -QString TelegramBotBase::help() { - return tr("Sorry, /help not implemented in @%1.").arg(api.botName()); -} - - -bool TelegramBotBase::loginUser(uint , const QString &msg) { - return (msg == "/start"); -} - - -void TelegramBotBase::messageFromUser(uint id, const QString &msg) { - if (msg.toLower() == "ping") api.sendMessage(id, "pong"); -} - - -void TelegramBotBase::newUser(uint, User) {} - -void TelegramBotBase::disconnectUser(uint id) { - users.remove(id); -} - diff --git a/telegram_bot/telegrambotbase.h b/telegram_bot/telegrambotbase.h deleted file mode 100644 index b6ecd17..0000000 --- a/telegram_bot/telegrambotbase.h +++ /dev/null @@ -1,54 +0,0 @@ -#ifndef TELEGRAMBOTBASE_H -#define TELEGRAMBOTBASE_H - -#include -#include "telegrambotapi.h" - -class TelegramBotBase : public QObject -{ - Q_OBJECT -public: - explicit TelegramBotBase(QObject *parent = 0); - TelegramBotAPI * getAPI() {return &api;} - - - -public slots: - void sendMessageToAll(const QString & message); - void setBotToken(QString token) {api.setBotToken(token);} - -protected: - struct User { - User() { - user_id = 0; - logged_in = false; - } - uint user_id; - bool logged_in; - QString user_name; - QDateTime last_timestamp; - }; - - const User & getUser(uint id) {return users[id];} - virtual QString welcome(uint id); - virtual QString loginMessage(uint id); - virtual QString help(); - virtual bool loginUser(uint id, const QString & msg); - virtual void messageFromUser(uint id, const QString & msg); - virtual void newUser(uint id, User user); - void disconnectUser(uint id); - -private slots: - void processMessage(TelegramBotAPI::Message msg); - -private: - QMap users; - TelegramBotAPI api; - - QString m_botToken; - -signals: - -}; - -#endif // TELEGRAMBOTBASE_H