diff --git a/microblogs/pumpio/pumpioaccount.cpp b/microblogs/pumpio/pumpioaccount.cpp index 7f23c5d5..ea909894 100644 --- a/microblogs/pumpio/pumpioaccount.cpp +++ b/microblogs/pumpio/pumpioaccount.cpp @@ -1,120 +1,132 @@ /* This file is part of Choqok, the KDE micro-blogging client Copyright (C) 2013 Andrea Scarpino 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 2 of the License or (at your option) version 3 or any later version accepted by the membership of KDE e.V. (or its successor approved by the membership of KDE e.V.), which shall act as a proxy defined in Section 14 of version 3 of the license. 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 http://www.gnu.org/licenses/ */ #include "pumpioaccount.h" +#include + #include "passwordmanager.h" #include "pumpiomicroblog.h" class PumpIOAccount::Private { public: QString consumerKey; QString consumerSecret; QString host; QString token; QString tokenSecret; + QOAuth::Interface *oAuth; }; PumpIOAccount::PumpIOAccount(PumpIOMicroBlog* parent, const QString& alias): Account(parent, alias), d(new Private) { d->host = configGroup()->readEntry("Host", QString()); d->token = configGroup()->readEntry("Token", QString()); d->consumerKey = configGroup()->readEntry("ConsumerKey", QString()); d->consumerSecret = Choqok::PasswordManager::self()->readPassword(QString("%1_consumerSecret").arg(alias)); d->tokenSecret = Choqok::PasswordManager::self()->readPassword(QString("%1_tokenSecret").arg(alias)); + d->oAuth = new QOAuth::Interface(new KIO::AccessManager(this), this); + d->oAuth->setConsumerKey(d->consumerKey.toLocal8Bit()); + d->oAuth->setConsumerSecret(d->consumerSecret.toLocal8Bit()); } PumpIOAccount::~PumpIOAccount() { + d->oAuth->deleteLater(); delete d; } QString PumpIOAccount::host() { return d->host; } void PumpIOAccount::setHost(const QString& host) { d->host = host; } QString PumpIOAccount::consumerKey() { return d->consumerKey; } void PumpIOAccount::setConsumerKey(const QString& consumerKey) { d->consumerKey = consumerKey; } QString PumpIOAccount::consumerSecret() { return d->consumerSecret; } void PumpIOAccount::setConsumerSecret(const QString& consumerSecret) { d->consumerSecret = consumerSecret; } QString PumpIOAccount::token() { return d->token; } void PumpIOAccount::setToken(const QString& token) { d->token = token; } QString PumpIOAccount::tokenSecret() { return d->tokenSecret; } void PumpIOAccount::setTokenSecret(const QString& tokenSecret) { d->tokenSecret = tokenSecret; } QString PumpIOAccount::webfingerID() { return username() + '@' + d->host; } +QOAuth::Interface* PumpIOAccount::oAuth() +{ + return d->oAuth; +} + void PumpIOAccount::writeConfig() { configGroup()->writeEntry("Host", d->host); configGroup()->writeEntry("Token", d->token ); configGroup()->writeEntry("ConsumerKey", d->consumerKey ); Choqok::PasswordManager::self()->writePassword(QString("%1_consumerSecret").arg(alias()), d->consumerSecret); Choqok::PasswordManager::self()->writePassword(QString("%1_tokenSecret").arg(alias()), d->tokenSecret); Choqok::Account::writeConfig(); } diff --git a/microblogs/pumpio/pumpioaccount.h b/microblogs/pumpio/pumpioaccount.h index eef2eebe..121bf885 100644 --- a/microblogs/pumpio/pumpioaccount.h +++ b/microblogs/pumpio/pumpioaccount.h @@ -1,63 +1,66 @@ /* This file is part of Choqok, the KDE micro-blogging client Copyright (C) 2013 Andrea Scarpino 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 2 of the License or (at your option) version 3 or any later version accepted by the membership of KDE e.V. (or its successor approved by the membership of KDE e.V.), which shall act as a proxy defined in Section 14 of version 3 of the license. 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 http://www.gnu.org/licenses/ */ #ifndef PUMPIOACCOUNT_H #define PUMPIOACCOUNT_H +#include + #include "account.h" class PumpIOMicroBlog; class PumpIOAccount : public Choqok::Account { Q_OBJECT public: explicit PumpIOAccount(PumpIOMicroBlog* parent, const QString& alias); virtual ~PumpIOAccount(); QString host(); void setHost(const QString& host); QString consumerKey(); void setConsumerKey(const QString& consumerKey); QString consumerSecret(); void setConsumerSecret(const QString& consumerSecret); QString token(); void setToken(const QString& token); QString tokenSecret(); void setTokenSecret(const QString& tokenSecret); QString webfingerID(); + QOAuth::Interface *oAuth(); virtual void writeConfig(); private: class Private; Private *d; }; #endif // PUMPIOACCOUNT_H diff --git a/microblogs/pumpio/pumpioeditaccountwidget.cpp b/microblogs/pumpio/pumpioeditaccountwidget.cpp index 60dad550..e4e47671 100644 --- a/microblogs/pumpio/pumpioeditaccountwidget.cpp +++ b/microblogs/pumpio/pumpioeditaccountwidget.cpp @@ -1,178 +1,178 @@ /* This file is part of Choqok, the KDE micro-blogging client Copyright (C) 2013 Andrea Scarpino 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 2 of the License or (at your option) version 3 or any later version accepted by the membership of KDE e.V. (or its successor approved by the membership of KDE e.V.), which shall act as a proxy defined in Section 14 of version 3 of the license. 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 http://www.gnu.org/licenses/ */ #include "pumpioeditaccountwidget.h" #include #include #include #include #include #include #include #include #include #include "choqoktools.h" #include "accountmanager.h" #include "pumpioaccount.h" #include "pumpiomicroblog.h" PumpIOEditAccountWidget::PumpIOEditAccountWidget(PumpIOMicroBlog* microblog, PumpIOAccount* account, QWidget* parent): ChoqokEditAccountWidget(account, parent) , m_account(account) { setupUi(this); connect(kcfg_authorize, SIGNAL(clicked(bool)), SLOT(authorizeUser())); if (m_account) { kcfg_alias->setText(m_account->alias()); kcfg_webfingerid->setText(m_account->webfingerID()); isAuthenticated(); } else { QString newAccountAlias = microblog->serviceName(); const QString servName = newAccountAlias; int counter = 1; while (Choqok::AccountManager::self()->findAccount(newAccountAlias)) { newAccountAlias = QString("%1%2").arg(servName).arg(counter); counter++; } m_account = new PumpIOAccount(microblog, newAccountAlias); setAccount(m_account); kcfg_alias->setText(newAccountAlias); } } PumpIOEditAccountWidget::~PumpIOEditAccountWidget() { } Choqok::Account* PumpIOEditAccountWidget::apply() { m_account->setAlias(kcfg_alias->text()); m_account->setUsername(kcfg_webfingerid->text().split('@')[0]); m_account->writeConfig(); return m_account; } void PumpIOEditAccountWidget::authorizeUser() { m_qoauth = new QOAuth::Interface(new KIO::Integration::AccessManager(this), this); if (m_account->consumerKey().isEmpty() || m_account->consumerSecret().isEmpty()) { registerClient(); } m_qoauth->setConsumerKey(m_account->consumerKey().toLocal8Bit()); m_qoauth->setConsumerSecret(m_account->consumerSecret().toLocal8Bit()); QOAuth::ParamMap oAuthParams; oAuthParams.insert("oauth_callback", "oob"); - QOAuth::ParamMap oAuthRequest = m_qoauth->requestToken("https://" + m_account->host() + "/oauth/request_token", + QOAuth::ParamMap oAuthRequest = m_qoauth->requestToken(m_account->host() + "/oauth/request_token", QOAuth::GET, QOAuth::HMAC_SHA1, oAuthParams); if (m_qoauth->error() == QOAuth::NoError) { const QString token = oAuthRequest.value(QOAuth::tokenParameterName()); const QString tokenSecret = oAuthRequest.value(QOAuth::tokenSecretParameterName()); - KUrl oAuthAuthorizeURL("https://" + m_account->host() + "/oauth/authorize"); + KUrl oAuthAuthorizeURL(m_account->host() + "/oauth/authorize"); oAuthAuthorizeURL.addQueryItem("oauth_token", token); Choqok::openUrl(oAuthAuthorizeURL); QString verifier = KInputDialog::getText( i18n("PIN"), - i18n("Enter the verifier code received from " + m_account->host())); + i18n("Enter the verifier code received from " + m_account->host().toAscii())); QOAuth::ParamMap oAuthVerifierParams; oAuthVerifierParams.insert("oauth_verifier", verifier.toUtf8()); - QOAuth::ParamMap oAuthVerifierRequest = m_qoauth->accessToken("https://" + m_account->host() + "/oauth/access_token", + QOAuth::ParamMap oAuthVerifierRequest = m_qoauth->accessToken(m_account->host() + "/oauth/access_token", QOAuth::POST, token.toLocal8Bit(), tokenSecret.toLocal8Bit(), QOAuth::HMAC_SHA1, oAuthVerifierParams); if (m_qoauth->error() == QOAuth::NoError) { m_account->setToken(oAuthVerifierRequest.value(QOAuth::tokenParameterName())); m_account->setTokenSecret(oAuthVerifierRequest.value(QOAuth::tokenSecretParameterName())); if (isAuthenticated()) { KMessageBox::information(this, i18n("Choqok is authorized successfully."), i18n("Authorized")); } } else { kDebug() << "QOAuth error: " + Choqok::qoauthErrorText(m_qoauth->error()); } } else { kDebug() << "QOAuth error: " + Choqok::qoauthErrorText(m_qoauth->error()); } } void PumpIOEditAccountWidget::registerClient() { - m_account->setHost(kcfg_webfingerid->text().split('@')[1]); - KUrl url("https://" + m_account->host() + "/api/client/register"); + m_account->setHost("https://" + kcfg_webfingerid->text().split('@')[1]); + KUrl url(m_account->host() + "/api/client/register"); QByteArray data("{" " \"type\": \"client_associate\", " " \"application_type\": \"native\", " " \"application_name\": \"Choqok\" " "}"); KIO::StoredTransferJob *job = KIO::storedHttpPost(data, url, KIO::HideProgressInfo); if ( !job ) { kDebug() << "Cannot create an http POST request!"; return; } job->addMetaData("content-type", "Content-Type: application/json"); QEventLoop loop; connect(job, SIGNAL(result(KJob*)), &loop, SLOT(quit())); job->start(); loop.exec(); if (job->error()) { kDebug() << "An error occurred in Job"; return; } else { KIO::StoredTransferJob *stj = qobject_cast(job); QJson::Parser parser; QVariantMap result = parser.parse(stj->data()).toMap(); m_account->setConsumerKey(result.value("client_id").toString()); m_account->setConsumerSecret(result.value("client_secret").toString()); } } bool PumpIOEditAccountWidget::validateData() { if (kcfg_webfingerid->text().isEmpty() || !kcfg_webfingerid->text().contains('@')) { return false; } else { return true; } } bool PumpIOEditAccountWidget::isAuthenticated() { if (m_account->token().isEmpty() || m_account->tokenSecret().isEmpty()) { return false; } else { kcfg_authorize->setIcon(KIcon("object-unlocked")); kcfg_authenticateLed->setState(KLed::On); kcfg_authenticateStatus->setText(i18n("Authenticated")); return true; } } diff --git a/microblogs/pumpio/pumpiomicroblog.cpp b/microblogs/pumpio/pumpiomicroblog.cpp index ff88f46c..2312130d 100644 --- a/microblogs/pumpio/pumpiomicroblog.cpp +++ b/microblogs/pumpio/pumpiomicroblog.cpp @@ -1,66 +1,193 @@ /* This file is part of Choqok, the KDE micro-blogging client Copyright (C) 2013 Andrea Scarpino 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 2 of the License or (at your option) version 3 or any later version accepted by the membership of KDE e.V. (or its successor approved by the membership of KDE e.V.), which shall act as a proxy defined in Section 14 of version 3 of the license. 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 http://www.gnu.org/licenses/ */ #include "pumpiomicroblog.h" +#include + +#include + #include +#include +#include #include "accountmanager.h" #include "pumpioaccount.h" #include "pumpioeditaccountwidget.h" K_PLUGIN_FACTORY( MyPluginFactory, registerPlugin < PumpIOMicroBlog > (); ) K_EXPORT_PLUGIN( MyPluginFactory( "choqok_pumpio" ) ) PumpIOMicroBlog::PumpIOMicroBlog(QObject* parent, const QVariantList& args): MicroBlog(MyPluginFactory::componentData(), parent) { setServiceName("Pump.io"); setServiceHomepageUrl("http://pump.io"); + QStringList timelineNames; + timelineNames << "Activity" << "Inbox"; + setTimelineNames(timelineNames); + setTimelinesInfo(); } PumpIOMicroBlog::~PumpIOMicroBlog() { } ChoqokEditAccountWidget* PumpIOMicroBlog::createEditAccountWidget(Choqok::Account* account, QWidget* parent) { PumpIOAccount *acc = qobject_cast(account); if (acc || !account) { return new PumpIOEditAccountWidget(this, acc, parent); } else { kDebug() << "Account passed here was not a valid PumpIOAccount!"; return 0; } } Choqok::Account* PumpIOMicroBlog::createNewAccount(const QString& alias) { PumpIOAccount *acc = qobject_cast( Choqok::AccountManager::self()->findAccount(alias) ); if (!acc) { return new PumpIOAccount(this, alias); } else { kDebug() << "Cannot create a new PumpIOAccount!"; return 0; } } + +void PumpIOMicroBlog::setTimelinesInfo() +{ + Choqok::TimelineInfo *t = new Choqok::TimelineInfo; + t->name = i18nc("Timeline Name", "Activity"); + t->description = i18nc("Timeline description", "You and your friends"); + t->icon = "user-home"; + m_timelinesInfos["Activity"] = t; + m_timelinesPaths["Activity"] = "/api/user/%1/inbox/major"; + + t = new Choqok::TimelineInfo; + t->name = i18nc("Timeline Name", "Inbox"); + t->description = i18nc("Timeline description", "Your incoming private messages"); + t->icon = "mail-folder-inbox"; + m_timelinesInfos["Inbox"] = t; + m_timelinesPaths["Inbox"] = "/api/user/%1/inbox/major"; +} + +void PumpIOMicroBlog::updateTimelines(Choqok::Account* theAccount) +{ + PumpIOAccount *acc = qobject_cast(theAccount); + if (acc) { + Q_FOREACH (const QString timeline, acc->timelineNames()) { + KUrl url(acc->host()); + url.addPath(m_timelinesPaths[timeline].arg(acc->username())); + KIO::StoredTransferJob *job = KIO::storedGet(url, KIO::Reload, KIO::HideProgressInfo); + if (!job) { + kDebug() << "Cannot create an http GET request!"; + continue; + } + const QString lastActivityID; + QOAuth::ParamMap oAuthParams; + oAuthParams.insert("count", "20"); + oAuthParams.insert("since", lastActivityID.toLocal8Bit()); + QByteArray authorization = acc->oAuth()->createParametersString(url.url(), QOAuth::GET, acc->token().toLocal8Bit(), + acc->tokenSecret().toLocal8Bit(), QOAuth::HMAC_SHA1, + oAuthParams, QOAuth::ParseForHeaderArguments); + job->addMetaData("customHTTPHeader", "Authorization: " + authorization); + m_timelinesRequests[job] = timeline; + m_accountJobs[job] = acc; + connect(job, SIGNAL(result(KJob*)), this, SLOT(slotUpdateTimeline(KJob*))); + job->start(); + } + } else { + kDebug() << "Error updating timelines"; + } +} + +Choqok::TimelineInfo* PumpIOMicroBlog::timelineInfo(const QString& timelineName) +{ + return m_timelinesInfos.value(timelineName); +} + +void PumpIOMicroBlog::slotUpdateTimeline(KJob* job) +{ + Choqok::Account *account = m_accountJobs.take(job); + if (job->error()) { + kDebug() << "Job Error: " << job->errorString(); + emit error(account, Choqok::MicroBlog::CommunicationError, i18n("An error occurred when fetching the timeline")); + return; + } + KIO::StoredTransferJob* j = qobject_cast(job); + QList list = readTimeline(account, j->data()); + emit timelineDataReceived(account, m_timelinesRequests.take(job), list); +} + +QList< Choqok::Post* > PumpIOMicroBlog::readTimeline(Choqok::Account* theAccount, + const QByteArray& buffer) +{ + QList posts; + QJson::Parser parser; + QVariantList list = parser.parse(buffer).toMap().take("items").toList(); + Q_FOREACH (const QVariant element, list) { + Choqok::Post* post = new Choqok::Post(); + readPost(theAccount, element.toMap(), post); + if (!post->postId.isNull()) { + posts.prepend(post); + } + } + + return posts; +} + +Choqok::Post* PumpIOMicroBlog::readPost(Choqok::Account* theAccount, const QVariantMap& var, + Choqok::Post* post) +{ + const QVariantMap object = var["object"].toMap(); + if (!object["deleted"].toString().isEmpty()) { + // Skip deleted posts + return 0; + } + QTextDocument content; + content.setHtml(object["content"].toString()); + if (object["displayName"].toString().isEmpty()) { + post->content = content.toPlainText(); + } else { + post->content = object["displayName"].toString() + '\n' + content.toPlainText(); + } + if (!object["fullImage"].toMap().isEmpty()) { + const QString imagePath = object["fullImage"].toMap().take("url").toString(); + if (!imagePath.isEmpty()) { + post->content += '\n' + imagePath; + } + } + post->creationDateTime = QDateTime::fromString(var["published"].toString(), + "yyyy-MM-dd'T'hh:mm:ss'Z'"); + const QVariantMap actor = var["actor"].toMap(); + post->author.userId = actor["id"].toString(); + post->author.userName = actor["preferredUsername"].toString(); + post->author.realName = actor["displayName"].toString(); + post->author.homePageUrl = actor["url"].toString(); + post->author.profileImageUrl = actor["image"].toMap().take("url").toString(); + post->source = var["generator"].toMap().take("displayName").toString(); + post->postId = var["id"].toString(); + post->link = var["url"].toString(); + return post; +} diff --git a/microblogs/pumpio/pumpiomicroblog.h b/microblogs/pumpio/pumpiomicroblog.h index 5d40316f..12a7bcec 100644 --- a/microblogs/pumpio/pumpiomicroblog.h +++ b/microblogs/pumpio/pumpiomicroblog.h @@ -1,40 +1,58 @@ /* This file is part of Choqok, the KDE micro-blogging client Copyright (C) 2013 Andrea Scarpino 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 2 of the License or (at your option) version 3 or any later version accepted by the membership of KDE e.V. (or its successor approved by the membership of KDE e.V.), which shall act as a proxy defined in Section 14 of version 3 of the license. 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 http://www.gnu.org/licenses/ */ #ifndef PUMPIOMICROBLOG_H #define PUMPIOMICROBLOG_H #include "microblog.h" +class KJob; + class PumpIOMicroBlog : public Choqok::MicroBlog { Q_OBJECT public: explicit PumpIOMicroBlog(QObject* parent, const QVariantList& args); virtual ~PumpIOMicroBlog(); virtual ChoqokEditAccountWidget* createEditAccountWidget(Choqok::Account* account, QWidget* parent); virtual Choqok::Account* createNewAccount(const QString& alias); + virtual Choqok::TimelineInfo* timelineInfo(const QString& timelineName); + virtual void updateTimelines(Choqok::Account* theAccount); + +private Q_SLOTS: + void slotUpdateTimeline(KJob* job); + +private: + QList readTimeline(Choqok::Account* theAccount, const QByteArray& buffer); + Choqok::Post* readPost(Choqok::Account* theAccount, const QVariantMap& var, Choqok::Post* post); + void setTimelinesInfo(); + + QHash m_timelinesPaths; + QMap m_timelinesInfos; + QMap m_accountJobs; + QMap m_timelinesRequests; + }; #endif // PUMPIOMICROBLOG_H \ No newline at end of file diff --git a/plugins/imagepreview/imagepreview.cpp b/plugins/imagepreview/imagepreview.cpp index 5ff61a81..708f5848 100644 --- a/plugins/imagepreview/imagepreview.cpp +++ b/plugins/imagepreview/imagepreview.cpp @@ -1,226 +1,247 @@ /* This file is part of Choqok, the KDE micro-blogging client Copyright (C) 2008-2012 Mehrdad Momeny 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 2 of the License or (at your option) version 3 or any later version accepted by the membership of KDE e.V. (or its successor approved by the membership of KDE e.V.), which shall act as a proxy defined in Section 14 of version 3 of the license. 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 http://www.gnu.org/licenses/ */ #include "imagepreview.h" #include #include #include "postwidget.h" #include #include K_PLUGIN_FACTORY( MyPluginFactory, registerPlugin < ImagePreview > (); ) K_EXPORT_PLUGIN( MyPluginFactory( "choqok_imagepreview" ) ) const QRegExp ImagePreview::mTwitpicRegExp("(http://twitpic.com/[^\\s<>\"]+[^!,\\.\\s<>'\"\\]])"); const QRegExp ImagePreview::mYFrogRegExp("(http://yfrog.[^\\s<>\"]+[^!,\\.\\s<>'\\\"\\]])"); const QRegExp ImagePreview::mTweetphotoRegExp("(http://tweetphoto.com/[^\\s<>\"]+[^!,\\.\\s<>'\"\\]])"); const QRegExp ImagePreview::mPlixiRegExp("(http://plixi.com/[^\\s<>\"]+[^!,\\.\\s<>'\"\\]])"); const QRegExp ImagePreview::mImgLyRegExp("(http://img.ly/[^\\s<>\"]+[^!,\\.\\s<>'\"\\]])"); const QRegExp ImagePreview::mTwitgooRegExp("(http://(([a-zA-Z0-9]+\\.)?)twitgoo.com/[^\\s<>\"]+[^!,\\.\\s<>'\"\\]])"); +const QRegExp ImagePreview::mPumpIORegExp("(https://([a-zA-Z0-9]+\\.)?[a-zA-Z0-9]+\\.[a-zA-Z]+/uploads/[a-zA-Z0-9]+/[0-9]{4}/[0-9]{1,2}/[0-9]{1,2}/[a-zA-Z0-9]+)(\\.[a-zA-Z]{3,4})"); ImagePreview::ImagePreview(QObject* parent, const QList< QVariant >& ) :Choqok::Plugin(MyPluginFactory::componentData(), parent), state(Stopped) { kDebug(); connect( Choqok::UI::Global::SessionManager::self(), SIGNAL(newPostWidgetAdded(Choqok::UI::PostWidget*,Choqok::Account*,QString)), this, SLOT(slotAddNewPostWidget(Choqok::UI::PostWidget*)) ); } ImagePreview::~ImagePreview() { } void ImagePreview::slotAddNewPostWidget(Choqok::UI::PostWidget* newWidget) { postsQueue.enqueue(newWidget); if(state == Stopped){ state = Running; QTimer::singleShot(1000, this, SLOT(startParsing())); } } void ImagePreview::startParsing() { // kDebug(); int i = 8; while( !postsQueue.isEmpty() && i>0 ){ parse(postsQueue.dequeue()); --i; } if(postsQueue.isEmpty()) state = Stopped; else QTimer::singleShot(500, this, SLOT(startParsing())); } void ImagePreview::parse(Choqok::UI::PostWidget* postToParse) { if(!postToParse) return; // kDebug(); int pos = 0; QStringList twitpicRedirectList; QStringList yfrogRedirectList; QStringList TweetphotoRedirectList; QStringList PlixiRedirectList; QStringList ImgLyRedirectList; QStringList TwitgooRedirectList; + QStringList PumpIORedirectList; QString content = postToParse->currentPost()->content; //Twitpic: http://www.twitpic.com/api.do while ((pos = mTwitpicRegExp.indexIn(content, pos)) != -1) { pos += mTwitpicRegExp.matchedLength(); twitpicRedirectList << mTwitpicRegExp.cap(0); kDebug()<fetchImage(twitpicUrl, Choqok::MediaManager::Async); } //YFrog: http://code.google.com/p/imageshackapi/wiki/YFROGurls // http://code.google.com/p/imageshackapi/wiki/YFROGthumbnails pos = 0; while ((pos = mYFrogRegExp.indexIn(content, pos)) != -1) { pos += mYFrogRegExp.matchedLength(); yfrogRedirectList << mYFrogRegExp.cap(0); kDebug()<fetchImage(yfrogThumbnailUrl, Choqok::MediaManager::Async); } //Tweetphoto; http://groups.google.com/group/tweetphoto/web/fetch-image-from-tweetphoto-url pos = 0; while ((pos = mTweetphotoRegExp.indexIn(content, pos)) != -1) { pos += mTweetphotoRegExp.matchedLength(); TweetphotoRedirectList << mTweetphotoRegExp.cap(0); kDebug()<fetchImage(TweetphotoUrl, Choqok::MediaManager::Async); } //Plixy; http://groups.google.com/group/plixi/web/fetch-photos-from-url pos = 0; while ((pos = mPlixiRegExp.indexIn(content, pos)) != -1) { pos += mPlixiRegExp.matchedLength(); PlixiRedirectList << mPlixiRegExp.cap(0); kDebug()<fetchImage(PlixiUrl, Choqok::MediaManager::Async); } //Img.ly; http://img.ly/api/docs pos = 0; while ((pos = mImgLyRegExp.indexIn(content, pos)) != -1) { pos += mImgLyRegExp.matchedLength(); ImgLyRedirectList << mImgLyRegExp.cap(0); kDebug()<fetchImage(ImgLyUrl, Choqok::MediaManager::Async); } //Twitgoo; http://twitgoo.com/docs/TwitgooHelp.htm pos = 0; while ((pos = mTwitgooRegExp.indexIn(content, pos)) != -1) { pos += mTwitgooRegExp.matchedLength(); TwitgooRedirectList << mTwitgooRegExp.cap(0); kDebug()<fetchImage(TwitgooUrl, Choqok::MediaManager::Async); } + //PumpIO + pos = 0; + QString baseUrl; + QString imageExtension; + while ((pos = mPumpIORegExp.indexIn(content, pos)) != -1) { + pos += mPumpIORegExp.matchedLength(); + PumpIORedirectList << mPumpIORegExp.cap(0); + baseUrl = mPumpIORegExp.cap(1); + imageExtension = mPumpIORegExp.cap(mPumpIORegExp.capturedTexts().length() - 1); + kDebug() << mPumpIORegExp.capturedTexts(); + } + Q_FOREACH (const QString &url, PumpIORedirectList) { + connect (Choqok::MediaManager::self(), SIGNAL(imageFetched(QString, QPixmap)), + SLOT(slotImageFetched(QString, QPixmap))); + const QString pumpIOUrl = baseUrl + "_thumb" + imageExtension; + mParsingList.insert(pumpIOUrl, postToParse); + mBaseUrlMap.insert(pumpIOUrl, url); + Choqok::MediaManager::self()->fetchImage(pumpIOUrl, Choqok::MediaManager::Async); + } } void ImagePreview::slotImageFetched(const QString& remoteUrl, const QPixmap& pixmap) { // kDebug(); Choqok::UI::PostWidget *postToParse = mParsingList.take(remoteUrl); QString baseUrl = mBaseUrlMap.take(remoteUrl); if(!postToParse) return; QString content = postToParse->content(); KUrl imgU(remoteUrl); imgU.setScheme("img"); QString imgUrl = imgU.prettyUrl(); // imgUrl.replace("http://","img://"); QString size; QPixmap pix = pixmap; if(pixmap.width() > 200) { pix = pixmap.scaledToWidth(200); } else if(pixmap.height() > 200) { pix = pixmap.scaledToHeight(200); } postToParse->mainWidget()->document()->addResource(QTextDocument::ImageResource, imgUrl, pix); content.replace(QRegExp('>'+baseUrl+'<'), "><"); postToParse->setContent(content); } diff --git a/plugins/imagepreview/imagepreview.h b/plugins/imagepreview/imagepreview.h index c0fdf707..2e42c4ce 100644 --- a/plugins/imagepreview/imagepreview.h +++ b/plugins/imagepreview/imagepreview.h @@ -1,75 +1,76 @@ /* This file is part of Choqok, the KDE micro-blogging client Copyright (C) 2008-2012 Mehrdad Momeny 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 2 of the License or (at your option) version 3 or any later version accepted by the membership of KDE e.V. (or its successor approved by the membership of KDE e.V.), which shall act as a proxy defined in Section 14 of version 3 of the license. 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 http://www.gnu.org/licenses/ */ #ifndef IMAGEPREVIEW_H #define IMAGEPREVIEW_H #include "plugin.h" #include #include #include namespace KIO { class Job; } class KJob; namespace Choqok { namespace UI { class PostWidget; } } class KConfigGroup; class ImagePreview : public Choqok::Plugin { Q_OBJECT public: ImagePreview( QObject* parent, const QList< QVariant >& args ); ~ImagePreview(); protected slots: void slotAddNewPostWidget( Choqok::UI::PostWidget *newWidget ); void startParsing(); void slotImageFetched(const QString &remoteUrl,const QPixmap &pixmap); private: enum ParserState{ Running = 0, Stopped }; ParserState state; void parse( Choqok::UI::PostWidget *postToParse ); QQueue< QPointer > postsQueue; QMap > mParsingList;//remoteUrl, Post QMap mBaseUrlMap;//remoteUrl, BaseUrl static const QRegExp mTwitpicRegExp; static const QRegExp mYFrogRegExp; static const QRegExp mTweetphotoRegExp; static const QRegExp mPlixiRegExp; static const QRegExp mImgLyRegExp; static const QRegExp mTwitgooRegExp; + static const QRegExp mPumpIORegExp; }; #endif // IMAGEPREVIEW_H