kde-extraapps/kdeplasma-addons/libs/rtm/request.cpp
2015-01-15 17:07:43 +00:00

158 lines
3.8 KiB
C++

/*
* Copyright 2009 Andrew Stromme <astromme@chatonka.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Library General Public License as
* published by the Free Software Foundation; either version 2, 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 Library General Public
* License along with this program; if not, write to the
* Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include "request.h"
#include "request_p.h"
#include <QTime>
#include <QMapIterator>
#include <QDateTime>
#include <QCryptographicHash>
#include <QCoreApplication>
#include <QStringList>
#include <QtDebug>
#include <QTimer>
RTM::Request::Request()
: d(new RTM::RequestPrivate(this))
{
}
RTM::Request::Request(const QString &method, const QString &apiKey, const QString &sharedSecret, const QString&baseUrl)
: d(new RTM::RequestPrivate(this))
{
if (!method.isEmpty())
d->arguments.insert("method", method);
d->baseUrl = baseUrl;
d->apiKey = apiKey;
d->sharedSecret = sharedSecret;
d->arguments.insert("api_key", apiKey);
d->m_state = RTM::Mutable;
d->retries = 0;
}
QString RTM::Request::response() const
{
return d->m_response;
}
RTM::State RTM::Request::state() const
{
return d->m_state;
}
void RTM::Request::setReadOnly(bool readOnly)
{
d->m_readOnly = readOnly;
}
bool RTM::Request::readOnly() const
{
return d->m_readOnly;
}
void RTM::Request::addArgument(const QString &name, const QString &value) {
d->arguments.insert(name, value);
}
void RTM::Request::sendRequest()
{
static QDateTime lastRequest = QDateTime::fromMSecsSinceEpoch(QDateTime::currentMSecsSinceEpoch() - 1050);
static unsigned int queueSize = 0;
qint64 margin = lastRequest.msecsTo(QDateTime::currentDateTime());
// Follow RTM's TOS and only do 1 request per second.
if (margin <= 1000) {
const int timeout = 1000 * (queueSize + 1) - margin + queueSize * 2 + 1;
QTimer::singleShot(timeout, this, SLOT(sendRequest()));
//qDebug() << "Postponing Job for"<<timeout<<"ms";
++queueSize;
return;
}
queueSize = 0;
QString url = requestUrl();
qDebug() << "Request ready. Url is: " << url;
d->accessManager->get(QNetworkRequest(url));
lastRequest = QDateTime::currentDateTime();
}
QString RTM::Request::method() const {
return d->arguments.value("method");
}
void RTM::Request::sign() {
QString unistring = d->sharedSecret;
QStringList keys = d->arguments.keys();
qSort(keys);
Q_FOREACH (const QString& key, keys) {
unistring.append(key);
unistring.append(d->arguments.value(key));
}
QString hash = QCryptographicHash::hash(unistring.toUtf8(), QCryptographicHash::Md5).toHex();
d->arguments.insert("api_sig", hash);
d->m_state = RTM::Hashed;
}
void RTM::Request::unsign() {
d->arguments.remove("api_sig");
}
QString RTM::Request::requestUrl()
{
switch(d->m_state) {
case RTM::Mutable:
sign();
break;
case RTM::Hashed:
unsign();
sign();
break;
case RTM::RequestSent:
break;
case RTM::RequestReceived:
break;
}
//qDebug() << "Creating url";
QString url = d->baseUrl;
QStringList keys = d->arguments.keys();
foreach (const QString &key, keys)
url.append('&' + key + '=' + d->arguments.value(key));
return url;
}
QString RTM::Request::apiKey() const
{
return d->apiKey;
}
QString RTM::Request::sharedSecret() const
{
return d->sharedSecret;
}
RTM::Request::~Request() {
}
#include "moc_request.cpp"