/* * Copyright 2009 Andrew Stromme * * 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 #include #include #include #include #include #include #include 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"<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"