Представляю вам новую Qt библиотеку для работы с vk api, которая может пригодиться вам при создании любых настольных и мобильных приложений, взаимодействующих с vk. Проект родился из vkontakte плагина для qutIM’а и перерос в отдельную независимую библиотеку, которой теперь может пользоваться каждый.
Краткий обзор
Vreen это обёртка над vk.com api, написанная на C++11/Qt, предназначенная для быстрого и простого создания мобильных и настольных приложений, а также встраивания взаимодействия с vk.com api в уже существующие приложения. Библиотека поддерживает несколько способов авторизации и позволяет при необходимости добавлять свои. Также в vreen существует полноценная привязка к qml, что позволяет создавать приложения, не написав ни единой строчки на C++. Для уменьшения количества обязательных зависимостей все способы авторизации вынесены в отдельные статические библиотеки.
Основные возможности:
- Поддержка любых видов диалогов в том числе и групповых чатов.
- Поддержка просмотра новостных лент, стен.
- Работа с комментариями, в том числе добавления, лайки и репосты.
- Поддержка работы с вложениями.
- Поддержка ростера в том числе отслеживание статуса собеседников.
- Поддержка аудиозаписей.
- Возможность напрямую работать с API из qml в привычном для многих XHTTPRequest стиле.
- Расширяемость.
- Свободная LGPL лицензия, позволяющая использовать библиотеку с проприетарными приложениям.
Основы:
Базовые классы для работы с API:
- Connection — класс, основанный на QNetworkAccessManager’е, выполняющий авторизацию и непосредственно реализующий запросы к API.
- Reply — класс отслеживает выполнение запроса.
- Longpoll — класс, выполняющий опрос сервера на предмет событий.
- Roster — класс, управляющий списком друзей.
- Client — базовый класс, который сшивает всё в единое целое.
Выполнение запросов к API:
Простой запрос:
QVariantMap args; args.insert("uids", join(ids)); args.insert("fields", fields.join(",")); auto reply = d->client->request("users.get", args); reply->connect(reply, SIGNAL(resultReady(const QVariant&)), this, SLOT(_q_friends_received(const QVariant&)));
Сигнал resultReady кидается в случае завершения запроса и содержит в response сконвертированный в QVariant json ответ от сервера или ничего в случае ошибки, код ошибки в этом случае содержится в reply->error()
Помимо этого можно скрыть обработку результата от получателя, добавив в reply функцию-обработчик результата, в этом случае результат будет можно получить при помощи вызова метода reply->result(), результат будет возращен в виде QVariant’а, поэтому его нужно будет еще дополнительно преобразовать при помощи QVariant::fromValue.
QVariantMap args; //TODO add chat messages support and contact check args.insert("uid", message.toId()); args.insert("message", message.body()); args.insert("title", message.subject()); return request ("messages.send", args, [](const QVariant &response) -> QVariant { return response.toInt(); });
Для того, чтобы четко обозначить тип возращаемого значения можно применить следующую шаблонную магию:
typedef ReplyBase<int> SendMessageReply; QVariantMap args; //TODO add chat messages support and contact check args.insert("uid", message.toId()); args.insert("message", message.body()); args.insert("title", message.subject()); return request<SendMessageReply> ("messages.send", args, [](const QVariant &response) -> QVariant { return response.toInt(); });
В результате в слоте SendMessageReply::result() будет возращать int вместо QVariant’а.
auto reply = static_cast<Vreen::SendMessageReply*>(sender()); m_unreachedMessagesCount--; int mid = reply->result();
В целом, все взаимодействие с API получается простым и прозрачным.
Получение и сборка
Vreen использует субмодули и поэтому самым оптимальным способом получения исходников является.
$ git clone git://github.com/gorthauer/vreen.git $ cd vreen $ git submodule update --init
Для сборки необходимы cmake 2.8, Qt 4.7.4, и любой компилятор с базовой поддержкой С++11 (gcc 4.4+, clang 3.0+, msvc2010+).
Сама сборка достаточно тривиальна:
$ mkdir build $ cd build $ cmake .. -DCMAKE_INSTALL_PREFIX=/usr $ make $ make install (sudo)
Если будут возникать вопросы относительно сборки релизной или дебажной версии, то лучше просто обратитесь к документации по cmake. В качестве экспериментального варианта поддерживается сборка при помощи qbs. Существует возможность собрать библиотеку при помощи qmake’, но данный способ не является официально поддерживаемым.
Использование в C++ проекте
Подключение
Для подключения к другим проектам в Vreen’е используется pkg-config, поэтому для подключения vreen’а со стандартым методом авторизации через браузер достаточно добавить в pro файл строчки.
CONFIG += link_pkgconfig PKGCONFIG += vreen \ vreenoauth
В случае систем, которые не поддерживают pkgconfig, можно или вручную добавить LIBS и INCLUDEPATH или написать find скрипт для cmake или qbs.
Желающие могут помочь мне написать prf файл для Qt.
Использование
Давайте в качестве примера напишем небольшое консольное приложение, которое будет вытаскивать все номера телефонов у списка друзей.
Для начала просто инициализируем клиента, указав ему способ подключения, идентификатор приложения, а также попросим его самостоятельно создавать окошко с разрешением для доступа из приложения к api.
auto auth = new Vreen::OAuthConnection(3220807, this); //в качестве clientId используйте собственный auth->setConnectionOption(Vreen::Connection::ShowAuthDialog, true); //заставляет клиент самостоятельно создавать окошко авторизации. auth->setConnectionOption(Vreen::Connection::KeepAuthData, true); //заставляет хранить токен между сессиями setConnection(auth); connect(this, SIGNAL(onlineStateChanged(bool)), SLOT(onOnlineChanged(bool))); connect(roster(), SIGNAL(syncFinished(bool)), SLOT(onSynced(bool)));
После того, как клиент успешно подключится к api, будет вызван слот onOnlineChanged в котором мы запросим у ростера список друзей. При запросе можно выбирать поля, которые хочется получить. Существует несколько макросов с наиболее распространёнными вариантами полей VK_COMMON_FIELDS, VK_EXTENDED_FIELDS и VK_ALL_FIELDS для всех известных полей.
Описание полей и получаемых свойств можно прочитать здесьu.
В данном случае нас интересует всего три поля и нет необходимости напрягать сервер более тяжелыми запросами.
roster()->sync(QStringList() << QLatin1String("first_name") << QLatin1String("last_name") << QLatin1String("contacts"));
После успешного завершения синхронизации ростера просто выведем на экран результат:
qDebug() << tr("-- %1 contacts recieved").arg(roster()->buddies().count()); foreach (auto buddy, roster()->buddies()) { QString homeNumber = buddy->property("_q_home_phone").toString(); QString mobileNumber = buddy->property("_q_mobile_phone").toString(); qDebug() << tr("name: %1, home: %2, mobile: %3").arg(buddy->name()) .arg(homeNumber.isEmpty() ? tr("unknown") : homeNumber) .arg(mobileNumber.isEmpty() ? tr("unknown") : mobileNumber); }
Все свойства, которые еще не реализованы штатно для контактов будут иметь префикс _q_, остальные же можно получить через getter’ы или через имена, указанные в Q_PROPERTY.
В качестве второго примера попробуем воспользоваться qml api и получим список друзей.
Импортируем в qml поддержку Vreen’а:
import com.vk.api 1.0
И создадим клиента:
Client { id: client connection: conn //используем в качестве подключения и авторизации известный по C++ примеру метод } OAuthConnection { id: conn Component.onCompleted: { //Не забудем установить для него те же самые свойства, что и в случае с photoview'ером setConnectionOption(Connection.ShowAuthDialog, true); setConnectionOption(Connection.KeepAuthData, true); } clientId: 3220807 displayType: OAuthConnection.Popup //из всех окошек авторизации это оказалось наиболее удобным }
Подключаться будем просто через client.connectToHost, в появившемся окошке подтверждения будет возможность вписать логин и пароль, поэтому можно не создавать отдельные поля для ввода, а ограничимся крайне лаконичным приглашением.
Для отображения списка диалогов можно воспользоваться готовой моделью из com.vk.api 1.0:
DialogsModel { id: dialogsModel client: client }
Для получения списка последних диалогов достаточно просто после подключения запросить список:
Connections { target: client onOnlineChanged: { if (client.online) { client.roster.sync(); dialogsModel.getDialogs(0, //смещение относительно последнего элемента 15, //число элементов 160 //максимальная длина сообщения ); } } }
Доступные для делегата свойства модели можно подсмотреть в коде её реализации:
roles[SubjectRole] = "subject"; roles[BodyRole] = "body"; roles[FromRole] = "from"; roles[ToRole] = "to"; roles[ReadStateRole] = "unread"; roles[DirectionRole] = "incoming"; roles[DateRole] = "date"; roles[IdRole] = "mid"; roles[AttachmentRole] = "attachments"; roles[ChatIdRole] = "chatId";
С помощью использования этих полей можно получить вполне опрятный на вид список диалогов:
Аналогичным образом создадим фотоальбом:
Причем хочется заметить, что в случае создания фотоальбома мы работаем через qml напрямую с vk.api
function getAll(ownerId, count, offset) { if (!offset) offset = 0; if (!count) count = 200; var args = { "owner_id" : ownerId, "offset" : offset, "count" : count, "extended" : 0 } var reply = client.request("photos.getAll", args) reply.resultReady.connect(function(response) { var count = response.shift() for (var index in response) { var photo = response[index] model.append(photo) } }) }
Получается очень кратко и лаконично.
Заключение
Текущая версия vreen’а — 0.9.5, то есть фактически это уже почти релиз, а это значит, что API по большей части уже не будет меняться и будет поддерживаться бинарная совместимость между версиями, а значит можно уже смело присоединяться к использованию и тестированию в реальных условиях.
На данный момент поддержка API еще очень неполная, но само написание оберток над ним максимально упрощено, так, что буду рад всем патчам с реализацией различных возможностей.
По остальным вопросам готов ответить в личку или в jabber’е, который можно найти в профиле.
Fork me with github.
ссылка на оригинал статьи http://habrahabr.ru/post/157081/
Добавить комментарий