[prev in list] [next in list] [prev in thread] [next in thread] 

List:       kde-commits
Subject:    [digikam/gsoc18-twitter-onedrive] core/utilities/assistants/webservices/twitter: twitter api under
From:       Tarek Talaat <null () kde ! org>
Date:       2018-07-31 21:27:44
Message-ID: E1fkcBE-00056z-Ru () code ! kde ! org
[Download RAW message or body]

Git commit 0dcd9b61688dfe5a0e442cecd13a678a9606cf33 by Tarek Talaat.
Committed on 31/07/2018 at 11:01.
Pushed by tarektalaat into branch 'gsoc18-twitter-onedrive'.

twitter api under development

A  +110  -0    core/utilities/assistants/webservices/twitter/twitteritem.h     \
[License: GPL (v2+)] A  +43   -0    \
core/utilities/assistants/webservices/twitter/twittermpform.cpp     [License: \
UNKNOWN]  * A  +52   -0    \
core/utilities/assistants/webservices/twitter/twittermpform.h     [License: GPL \
(v2+)] A  +53   -0    \
core/utilities/assistants/webservices/twitter/twitternewalbumdlg.cpp     [License: \
GPL (v2+)] A  +60   -0    \
core/utilities/assistants/webservices/twitter/twitternewalbumdlg.h     [License: GPL \
(v2+)] A  +618  -0    core/utilities/assistants/webservices/twitter/twittertalker.cpp \
[License: UNKNOWN]  * A  +86   -0    \
core/utilities/assistants/webservices/twitter/twittertalker.h     [License: UNKNOWN]  \
* A  +71   -0    core/utilities/assistants/webservices/twitter/twitterwidget.cpp     \
[License: GPL (v2+)] A  +68   -0    \
core/utilities/assistants/webservices/twitter/twitterwidget.h     [License: GPL \
(v2+)] A  +449  -0    core/utilities/assistants/webservices/twitter/twitterwindow.cpp \
[License: UNKNOWN]  * A  +98   -0    \
core/utilities/assistants/webservices/twitter/twitterwindow.h     [License: GPL \
(v2+)]

The files marked with a * at the end have a non valid license. Please read: \
https://community.kde.org/Policies/Licensing_Policy and use the headers which are \
listed at that page.


https://commits.kde.org/digikam/0dcd9b61688dfe5a0e442cecd13a678a9606cf33

diff --git a/core/utilities/assistants/webservices/twitter/twitteritem.h \
b/core/utilities/assistants/webservices/twitter/twitteritem.h new file mode 100644
index 0000000000..1114bd827a
--- /dev/null
+++ b/core/utilities/assistants/webservices/twitter/twitteritem.h
@@ -0,0 +1,110 @@
+/* ============================================================
+ *
+ * This file is a part of digiKam project
+ * http://www.digikam.org
+ *
+ * Date        : 2018-06-29
+ * Description : a tool to export images to Onedrive web service
+ *
+ * Copyright (C) 2013      by Pankaj Kumar <me at panks dot me>
+ * Copyright (C) 2013-2018 by Gilles Caulier <caulier dot gilles at gmail dot com>
+ *
+ * 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, 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.
+ *
+ * ============================================================ */
+
+ #ifndef DIGIKAM_TW_ITEM_H
+ #define DIGIKAM_TW_ITEM_H
+
+ // Qt includes
+
+ #include <QString>
+
+ namespace Digikam
+ {
+
+ class TwUser
+ {
+ public:
+
+     TwUser()
+     {
+         id         = 0;
+         uploadPerm = false;
+     }
+
+     void clear()
+     {
+         id         = 0;
+         name.clear();
+         profileURL = QStringLiteral("https://www.facebook.com");
+         uploadPerm = true;
+     }
+
+     long long id;
+
+     QString   name;
+     QString   profileURL;
+     bool      uploadPerm;
+ };
+
+ // ---------------------------------------------------------------
+
+ /*enum TWPrivacy
+ {
+     FB_ME = 0,
+     FB_FRIENDS = 1,
+     FB_FRIENDS_OF_FRIENDS,
+     FB_NETWORKS,
+     FB_EVERYONE,
+     FB_CUSTOM
+ };*/
+
+ // ---------------------------------------------------------------
+
+ class TwAlbum
+ {
+ public:
+
+     TwAlbum()
+     {
+         //privacy = FB_FRIENDS;
+     }
+
+     QString   id;
+
+     QString   title;
+     QString   description;
+     QString   location;
+     //FbPrivacy privacy;
+     QString   url;
+ };
+
+ // ---------------------------------------------------------------
+
+ class TwPhoto
+ {
+ public:
+
+     TwPhoto()
+     {
+     }
+
+     QString id;
+
+     QString caption;
+     QString thumbURL;
+     QString originalURL;
+ };
+
+ } // namespace Digikam
+
+ #endif // DIGIKAM_TW_ITEM_H
diff --git a/core/utilities/assistants/webservices/twitter/twittermpform.cpp \
b/core/utilities/assistants/webservices/twitter/twittermpform.cpp new file mode \
100644 index 0000000000..f2b1df92ee
--- /dev/null
+++ b/core/utilities/assistants/webservices/twitter/twittermpform.cpp
@@ -0,0 +1,43 @@
+// local includes
+
+#include "twittermpform.h"
+
+// Qt includes
+
+#include <QFile>
+
+// Local includes
+
+#include "digikam_debug.h"
+
+namespace Digikam
+{
+
+TwMPForm::TwMPForm()
+{
+}
+
+TwMPForm::~TwMPForm()
+{
+}
+
+bool TwMPForm::addFile(const QString& imgPath)
+{
+    QFile file(imgPath);
+
+    if (!file.open(QIODevice::ReadOnly))
+    {
+        return false;
+    }
+
+    m_buffer = file.readAll();
+
+    return true;
+}
+
+QByteArray TwMPForm::formData() const
+{
+    return m_buffer;
+}
+
+} // namespace Digikam
diff --git a/core/utilities/assistants/webservices/twitter/twittermpform.h \
b/core/utilities/assistants/webservices/twitter/twittermpform.h new file mode 100644
index 0000000000..73f14b7e22
--- /dev/null
+++ b/core/utilities/assistants/webservices/twitter/twittermpform.h
@@ -0,0 +1,52 @@
+/* ============================================================
+ *
+ * This file is a part of digiKam project
+ * http://www.digikam.org
+ *
+ * Date        : 2018-06-29
+ * Description : a tool to export images to Onedrive web service
+ *
+ * Copyright (C) 2013      by Pankaj Kumar <me at panks dot me>
+ * Copyright (C) 2013-2018 by Gilles Caulier <caulier dot gilles at gmail dot com>
+ *
+ * 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, 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.
+ *
+ * ============================================================ */
+
+#ifndef DIGIKAM_TW_MPFORM_H
+#define DIGIKAM_TW_MPFORM_H
+
+// Qt includes
+
+#include <QByteArray>
+
+namespace Digikam
+{
+
+class TwMPForm
+{
+
+public:
+
+    explicit TwMPForm();
+    ~TwMPForm();
+
+    bool addFile(const QString& imgPath);
+    QByteArray formData() const;
+
+private:
+
+    QByteArray m_buffer;
+};
+
+} // namespace Digikam
+
+#endif // TW_MPFORM_H
diff --git a/core/utilities/assistants/webservices/twitter/twitternewalbumdlg.cpp \
b/core/utilities/assistants/webservices/twitter/twitternewalbumdlg.cpp new file mode \
100644 index 0000000000..bdb6cf0ad1
--- /dev/null
+++ b/core/utilities/assistants/webservices/twitter/twitternewalbumdlg.cpp
@@ -0,0 +1,53 @@
+/* ============================================================
+ *
+ * This file is a part of digiKam project
+ * http://www.digikam.org
+ *
+ * Date        : 2018-06-29
+ * Description : a tool to export images to Onedrive web service
+ *
+ * Copyright (C) 2013      by Pankaj Kumar <me at panks dot me>
+ * Copyright (C) 2013-2018 by Gilles Caulier <caulier dot gilles at gmail dot com>
+ *
+ * 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, 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.
+ *
+ * ============================================================ */
+
+ #include "twitternewalbumdlg.h"
+
+ // Local includes
+
+ #include "digikam_debug.h"
+ #include "twitteritem.h"
+
+namespace Digikam
+{
+
+TwNewAlbumDlg::TwNewAlbumDlg(QWidget* const parent, const QString& toolName)
+    : WSNewAlbumDialog(parent, toolName)
+{
+    hideDateTime();
+    hideDesc();
+    hideLocation();
+    getMainWidget()->setMinimumSize(300, 0);
+}
+
+TwNewAlbumDlg::~TwNewAlbumDlg()
+{
+}
+
+void TwNewAlbumDlg::getAlbumProperties(TwAlbum& album)
+{
+    album.title       = getTitleEdit()->text();
+    album.description = getDescEdit()->toPlainText();
+}
+
+} // namespace Digikam
diff --git a/core/utilities/assistants/webservices/twitter/twitternewalbumdlg.h \
b/core/utilities/assistants/webservices/twitter/twitternewalbumdlg.h new file mode \
100644 index 0000000000..382cdb129a
--- /dev/null
+++ b/core/utilities/assistants/webservices/twitter/twitternewalbumdlg.h
@@ -0,0 +1,60 @@
+/* ============================================================
+ *
+ * This file is a part of digiKam project
+ * http://www.digikam.org
+ *
+ * Date        : 2018-06-29
+ * Description : a tool to export images to Onedrive web service
+ *
+ * Copyright (C) 2013      by Pankaj Kumar <me at panks dot me>
+ * Copyright (C) 2013-2018 by Gilles Caulier <caulier dot gilles at gmail dot com>
+ *
+ * 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, 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.
+ *
+ * ============================================================ */
+
+ #ifndef DIGIKAM_TW_NEW_ALBUM_DLG_H
+ #define DIGIKAM_TW_NEW_ALBUM_DLG_H
+
+ // Qt includes
+
+ #include <QDialog>
+
+ // Local includes
+
+ #include "wsnewalbumdialog.h"
+
+ class QComboBox;
+
+ namespace Digikam
+ {
+
+ class TwAlbum;
+
+ class TwNewAlbumDlg : public WSNewAlbumDialog
+ {
+     Q_OBJECT
+
+ public:
+
+     explicit TwNewAlbumDlg(QWidget* const parent, const QString& toolName);
+     ~TwNewAlbumDlg();
+
+     void getAlbumProperties(TwAlbum& album);
+
+ private:
+   
+     friend class TwWindow;
+ };
+
+ } // namespace Digikam
+
+ #endif // DIGIKAM_TW_NEW_ALBUM_DLG_H
diff --git a/core/utilities/assistants/webservices/twitter/twittertalker.cpp \
b/core/utilities/assistants/webservices/twitter/twittertalker.cpp new file mode \
100644 index 0000000000..58124a5ba0
--- /dev/null
+++ b/core/utilities/assistants/webservices/twitter/twittertalker.cpp
@@ -0,0 +1,618 @@
+#include <twittertalker.h>
+
+// Qt includes
+
+#include <QJsonDocument>
+#include <QJsonParseError>
+#include <QJsonObject>
+#include <QJsonValue>
+#include <QJsonArray>
+#include <QByteArray>
+#include <QList>
+#include <QPair>
+#include <QFileInfo>
+#include <QWidget>
+#include <QMessageBox>
+#include <QApplication>
+#include <QDesktopServices>
+#include <QUrlQuery>
+#include <QWebEngineView>
+#include <QWebEnginePage>
+#include <QWebEngineProfile>
+#include <QWebEngineCookieStore>
+
+// Local includes
+
+#include "digikam_debug.h"
+#include "digikam_version.h"
+#include "wstoolutils.h"
+#include "twitterwindow.h"
+#include "twitteritem.h"
+#include "twittermpform.h"
+#include "previewloadthread.h"
+#include "o0settingsstore.h"
+#include "o1requestor.h"
+
+namespace Digikam
+{
+
+class TwTalker::Private
+{
+public:
+
+    enum State
+    {
+        OD_USERNAME = 0,
+        OD_LISTFOLDERS,
+        OD_CREATEFOLDER,
+        OD_ADDPHOTO
+    };
+
+public:
+
+    explicit Private()
+    {
+        clientId              =     QLatin1String("Kej10Xqld2SzYHpl1zPNXBkdz");
+        clientSecret          =     \
QLatin1String("u7012XOx5Xd4t2oH10UMsffY8NseowtsfrXscoOzi4I0c039MF"); +        //scope \
=     QLatin1String("User.Read Files.ReadWrite"); +
+        authUrl               =     \
QLatin1String("https://api.twitter.com/oauth/request_token"); +        \
requestTokenUrl       =     \
QLatin1String("https://api.twitter.com/oauth/authenticate"); +        accessTokenUrl  \
=     QLatin1String("https://api.twitter.com/oauth/access_token"); +
+        redirectUrl    =     QLatin1String("http://127.0.0.1:8000");
+
+        state          =     OD_USERNAME;
+        netMngr        =     0;
+        reply          =     0;
+        accessToken    =     "";
+    }
+
+public:
+
+    QString                clientId;
+    QString                clientSecret;
+    QString                authUrl;
+    QString                requestTokenUrl;
+    QString                accessTokenUrl;
+    QString                scope;
+    QString                redirectUrl;
+    QString                accessToken;
+
+    QWidget*               parent;
+
+    QNetworkAccessManager* netMngr;
+
+    QNetworkReply*         reply;
+
+    State                  state;
+
+    QByteArray             buffer;
+
+    DMetadata              meta;
+
+    QMap<QString,QString> urlParametersMap;
+
+    QWebEngineView*        view;
+
+    QSettings*             settings;
+
+    O1Twitter*                    o1Twitter;
+};
+TwTalker::TwTalker(QWidget* const parent)
+    : d(new Private)
+{
+    d->parent  = parent;
+    d->netMngr = new QNetworkAccessManager(this);
+
+    connect(d->netMngr, SIGNAL(finished(QNetworkReply*)),
+            this, SLOT(slotFinished(QNetworkReply*)));
+
+    d->o1Twitter = new O1Twitter(this);
+    d->o1Twitter->setClientId(d->clientId);
+    d->o1Twitter->setClientSecret(d->clientSecret);
+    d->o1Twitter->setLocalPort(8000);
+
+    d->settings                  = WSToolUtils::getOauthSettings(this);
+    O0SettingsStore* const store = new O0SettingsStore(d->settings, \
QLatin1String(O2_ENCRYPTION_KEY), this); +    \
store->setGroupKey(QLatin1String("twitter")); +    d->o1Twitter->setStore(store);
+
+    connect(d->o1Twitter, SIGNAL(linkingFailed()),
+            this, SLOT(slotLinkingFailed()));
+
+    connect(d->o1Twitter, SIGNAL(linkingSucceeded()),
+            this, SLOT(slotLinkingSucceeded()));
+
+    connect(d->o1Twitter, SIGNAL(openBrowser(QUrl)),
+            this, SLOT(slotOpenBrowser(QUrl)));
+}
+TwTalker::~TwTalker()
+{
+    if (d->reply)
+    {
+        d->reply->abort();
+    }
+    delete d;
+}
+void TwTalker::link()
+{
+    /*emit signalBusy(true);
+    QUrl url(d->requestTokenUrl);
+    QNetworkRequest netRequest(url);
+    netRequest.setHeader(QNetworkRequest::ContentTypeHeader, \
QLatin1String("application/json")); +    netRequest.setRawHeader("Authorization", \
QString::fromLatin1("OAuth oauth_callback= \"%1\"").arg(d->redirectUrl).toUtf8()); +  \
QNetworkAccessManager requestMngr; +    QNetworkReply* reply;
+    reply = requestMngr.post(netRequest);
+    if (reply->error() != QNetworkReply::NoError){
+
+    }
+    QByteArray buffer;
+    buffer.append(reply->readAll());
+    QString response = fromLatin1(buffer);
+
+    QMap<QString, QString> headers;
+
+    // Discard the first line
+    response = response.mid(response.indexOf('\n') + 1).trimmed();
+
+    foreach(QString line, response.split('\n')) {
+        int colon = line.indexOf(':');
+        QString headerName = line.left(colon).trimmed();
+        QString headerValue = line.mid(colon + 1).trimmed();
+
+        headers.insertMulti(headerName, headerValue);
+    }
+    QString oauthToken = headers[oauth_token];
+    QSting oauthTokenSecret = headers[oauth_token_secret];
+
+    QUrlQuery query(url);
+    query.addQueryItem(QLatin1String("client_id"), d->clientId);
+    query.addQueryItem(QLatin1String("scope"), d->scope);
+    query.addQueryItem(QLatin1String("redirect_uri"), d->redirectUrl);
+    query.addQueryItem(QLatin1String("response_type"), "token");
+    url.setQuery(query);
+
+    d->view = new QWebEngineView(d->parent);
+    d->view->setWindowFlags(Qt::Dialog);
+    d->view->load(url);
+    d->view->show();
+
+    connect(d->view, SIGNAL(urlChanged(QUrl)), this, SLOT(slotCatchUrl(QUrl)));*/
+
+    emit signalBusy(true);
+    d->o1Twitter->link();
+}
+void TwTalker::unLink()
+{
+    /*d->accessToken = "";
+    d->view->page()->profile()->cookieStore()->deleteAllCookies();
+    Q_EMIT oneDriveLinkingSucceeded();*/
+
+    d->o1Twitter->unlink();
+
+    d->settings->beginGroup(QLatin1String("Dropbox"));
+    d->settings->remove(QString());
+    d->settings->endGroup();
+}
+
+void TwTalker::slotOpenBrowser(const QUrl& url)
+{
+    qCDebug(DIGIKAM_WEBSERVICES_LOG) << "Open Browser...";
+    QDesktopServices::openUrl(url);
+}
+
+QMap<QString,QString> TwTalker::ParseUrlParameters(const QString &url)
+{
+  QMap<QString,QString> urlParameters;
+  if(url.indexOf('?')==-1)
+  {
+      return urlParameters;
+  }
+
+  QString tmp = url.right(url.length()-url.indexOf('?')-1);
+  tmp = tmp.right(tmp.length() - tmp.indexOf('#')-1);
+  QStringList paramlist = tmp.split('&');
+
+  for(int i=0;i<paramlist.count();i++)
+  {
+      QStringList paramarg = paramlist.at(i).split('=');
+      urlParameters.insert(paramarg.at(0),paramarg.at(1));
+  }
+
+  return urlParameters;
+}
+void TwTalker::slotLinkingFailed()
+{
+    qCDebug(DIGIKAM_WEBSERVICES_LOG) << "LINK to Twitter fail";
+    emit signalBusy(false);
+}
+void TwTalker::slotLinkingSucceeded()
+{
+    /*if (d->accessToken == "")
+    {
+        qCDebug(DIGIKAM_WEBSERVICES_LOG) << "UNLINK to Twitter ok";
+        emit signalBusy(false);
+        return;
+    }
+
+    qCDebug(DIGIKAM_WEBSERVICES_LOG) << "LINK to Twitter ok";
+    d->view->close();
+    emit signalLinkingSucceeded();*/
+
+
+    if (!d->o1Twitter->linked())
+    {
+        qCDebug(DIGIKAM_WEBSERVICES_LOG) << "UNLINK to Twitter ok";
+        emit signalBusy(false);
+        return;
+    }
+
+    qCDebug(DIGIKAM_WEBSERVICES_LOG) << "LINK to Twitter ok";
+    QVariantMap extraTokens = d->o1Twitter->extraTokens();
+    if (!extraTokens.isEmpty()) {
+        //emit extraTokensReady(extraTokens);
+        qDebug() << "Extra tokens in response:";
+        foreach (QString key, extraTokens.keys()) {
+            qDebug() << "\t" << key << ":" << \
(extraTokens.value(key).toString().left(3) + "..."); +        }
+    }
+    emit signalLinkingSucceeded();
+
+}
+
+bool TwTalker::authenticated()
+{
+    return d->o1Twitter->linked();
+}
+void TwTalker::cancel()
+{
+    if (d->reply)
+    {
+        d->reply->abort();
+        d->reply = 0;
+    }
+
+    emit signalBusy(false);
+}
+/*void TwTalker::upload(QByteArray& data){
+  QByteArray encoded = data.toBase64(QByteArray::Base64UrlEncoding);
+
+  QUrl url = QUrl("https://upload.twitter.com/1.1/media/upload.json");
+}*/
+bool TwTalker::addPhoto(const QString& imgPath, const QString& uploadFolder, bool \
rescale, int maxDim, int imageQuality) +{
+
+    //qDebug() << "Status update message:" << message.toLatin1().constData();
+    emit signalBusy(true);
+    TwMPForm form;
+    QImage image = PreviewLoadThread::loadHighQualitySynchronously(imgPath).copyQImage();
 +    qint64 imageSize = QFileInfo(imgPath).size();
+    qDebug() << "SIZE of image using qfileinfo:   " << imageSize;
+    qDebug() << " " ;
+    if (image.isNull())
+    {
+        return false;
+    }
+
+    QString path = WSToolUtils::makeTemporaryDir("twitter").filePath(QFileInfo(imgPath)
 +                                                 .baseName().trimmed() + \
QLatin1String(".jpg")); +
+    if (rescale && (image.width() > maxDim || image.height() > maxDim))
+    {
+        image = image.scaled(maxDim,maxDim, \
Qt::KeepAspectRatio,Qt::SmoothTransformation); +    }
+
+    image.save(path,"JPEG",imageQuality);
+
+    if (d->meta.load(imgPath))
+    {
+        d->meta.setImageDimensions(image.size());
+        d->meta.setImageOrientation(DMetadata::ORIENTATION_NORMAL);
+        d->meta.setImageProgramId(QLatin1String("digiKam"), digiKamVersion());
+        d->meta.setMetadataWritingMode((int)DMetadata::WRITETOIMAGEONLY);
+        d->meta.save(path);
+    }
+
+    if (!form.addFile(path))
+    {
+        emit signalBusy(false);
+        return false;
+    }
+    QString uploadPath = uploadFolder + \
QUrl(QUrl::fromLocalFile(imgPath)).fileName(); +    if(form.formData().isEmpty()){
+      qDebug() << "Form DATA Empty:";
+    }
+    if(form.formData().isNull()){
+      qDebug() << "Form DATA null:";
+    }
+    QUrl url = QUrl("https://upload.twitter.com/1.1/media/upload.json");
+
+    O1Requestor* requestor = new O1Requestor(d->netMngr, d->o1Twitter, this);
+    QList<O0RequestParameter> reqParams = QList<O0RequestParameter>();
+
+    //These are the parameters passed for the first step in chuncked media upload.
+    //reqParams << O0RequestParameter(QByteArray("command"), QByteArray("INIT"));
+    //reqParams << O0RequestParameter(QByteArray("media_type"), \
QByteArray("image/jpeg")); +    //reqParams << \
O0RequestParameter(QByteArray("total_bytes"), \
QString::fromLatin1("%1").arg(imageSize).toUtf8()); +
+    reqParams << O0RequestParameter(QByteArray("media"), form.formData());
+
+    QByteArray postData = O1::createQueryParameters(reqParams);
+
+
+    QNetworkRequest request(url);
+    request.setHeader(QNetworkRequest::ContentTypeHeader, "multipart/form-data");
+    QNetworkReply *reply2 = requestor->post(request, reqParams, postData);
+    qDebug() << "reply size:              " << reply2->readBufferSize();  //always \
returns 0 +    QByteArray replyData = reply2->readAll();
+    qDebug() << "Media reply:" << replyData; //always Empty
+
+
+    //uncomment this to try to post a tweet
+    QUrl url2 = QUrl("https://api.twitter.com/1.1/statuses/update.json");
+    reqParams = QList<O0RequestParameter>();
+    reqParams << O0RequestParameter(QByteArray("status"), "Hello");
+    //reqParams << O0RequestParameter(QByteArray("media_ids"), mediaId.toUtf8());
+
+    postData = O1::createQueryParameters(reqParams);
+
+    request.setUrl(url2);
+    request.setHeader(QNetworkRequest::ContentTypeHeader, O2_MIME_TYPE_XFORM);
+
+    QNetworkReply *reply = requestor->post(request, reqParams, postData);
+    connect(reply, SIGNAL(finished()), this, SLOT(slotTweetDone()));
+
+
+    connect(reply2, SIGNAL(finished()), this, SLOT(reply2finish()));
+    emit signalBusy(true);
+    return true;
+}
+void TwTalker::reply2finish(){
+  qDebug() << "In Reply2:";
+  QNetworkReply *reply2 = qobject_cast<QNetworkReply *>(sender());
+  QString mediaId;
+  if (reply2->error() != QNetworkReply::NoError) {
+
+      qDebug() << "ERROR:" << reply2->errorString();
+      qDebug() << "Content:" << reply2->readAll();
+      emit signalAddPhotoFailed(i18n("Failed to upload photo"));
+  } else {
+    QByteArray replyData = reply2->readAll();
+    QJsonDocument doc      = QJsonDocument::fromJson(replyData);
+    qDebug() << "Media reply:" << replyData;
+    QJsonObject jsonObject = doc.object();
+    mediaId = jsonObject[QLatin1String("media_id")].toString();
+  }
+
+  qDebug() << "Media ID:" << mediaId;
+}
+void TwTalker::getUserName()
+{
+    QUrl url(QLatin1String("https://graph.microsoft.com/v1.0/me"));
+
+    QNetworkRequest netRequest(url);
+    netRequest.setRawHeader("Authorization", QString::fromLatin1("bearer \
%1").arg(d->accessToken).toUtf8()); +    \
netRequest.setHeader(QNetworkRequest::ContentTypeHeader, \
QLatin1String("application/json")); +
+    d->reply = d->netMngr->get(netRequest);
+    qCDebug(DIGIKAM_WEBSERVICES_LOG) << "AFter Request Usar " << d->reply;
+    d->state = Private::OD_USERNAME;
+    d->buffer.resize(0);
+    emit signalBusy(true);
+}
+void TwTalker::slotTweetDone()
+{
+    qDebug() << "In slotTweetDone:";
+    QNetworkReply *reply = qobject_cast<QNetworkReply *>(sender());
+    if (reply->error() != QNetworkReply::NoError) {
+        qDebug() << "ERROR:" << reply->errorString();
+        qDebug() << "Content:" << reply->readAll();
+        emit signalAddPhotoFailed(i18n("Failed to upload photo"));
+    } else {
+        qDebug() << "Tweet posted sucessfully!";
+        emit signalAddPhotoSucceeded();
+    }
+
+}
+/*bool TwTalker::addPhoto(const QString& imgPath, const QString& uploadFolder, bool \
rescale, int maxDim, int imageQuality) +{
+    qCDebug(DIGIKAM_WEBSERVICES_LOG) << "PATH " << imgPath;
+    qCDebug(DIGIKAM_WEBSERVICES_LOG) << "Folder " << uploadFolder;
+    qCDebug(DIGIKAM_WEBSERVICES_LOG) << "Others: " << rescale << " " << maxDim << " \
" <<imageQuality; +    if (d->reply)
+    {
+        d->reply->abort();
+        d->reply = 0;
+    }
+
+    emit signalBusy(true);
+
+    ODMPForm form;
+    QImage image = PreviewLoadThread::loadHighQualitySynchronously(imgPath).copyQImage();
 +
+    if (image.isNull())
+    {
+        return false;
+    }
+
+    QString path = WSToolUtils::makeTemporaryDir("twitter").filePath(QFileInfo(imgPath)
 +                                                 .baseName().trimmed() + \
QLatin1String(".jpg")); +
+    if (rescale && (image.width() > maxDim || image.height() > maxDim))
+    {
+        image = image.scaled(maxDim,maxDim, \
Qt::KeepAspectRatio,Qt::SmoothTransformation); +    }
+
+    image.save(path,"JPEG",imageQuality);
+
+    if (d->meta.load(imgPath))
+    {
+        d->meta.setImageDimensions(image.size());
+        d->meta.setImageOrientation(DMetadata::ORIENTATION_NORMAL);
+        d->meta.setImageProgramId(QLatin1String("digiKam"), digiKamVersion());
+        d->meta.setMetadataWritingMode((int)DMetadata::WRITETOIMAGEONLY);
+        d->meta.save(path);
+    }
+
+    if (!form.addFile(path))
+    {
+        emit signalBusy(false);
+        return false;
+    }
+
+    QString uploadPath = uploadFolder + \
QUrl(QUrl::fromLocalFile(imgPath)).fileName(); +    QUrl \
url(QString::fromLatin1("https://graph.microsoft.com/v1.0/me/drive/root:/%1:/content").arg(uploadPath));
 +
+    QNetworkRequest netRequest(url);
+    netRequest.setHeader(QNetworkRequest::ContentTypeHeader, \
QLatin1String("application/octet-stream")); +    \
netRequest.setRawHeader("Authorization", QString::fromLatin1("bearer \
{%1}").arg(d->accessToken).toUtf8()); +
+    d->reply = d->netMngr->put(netRequest, form.formData());
+
+    d->state = Private::OD_ADDPHOTO;
+    d->buffer.resize(0);
+    emit signalBusy(true);
+    return true;
+}*/
+void TwTalker::slotFinished(QNetworkReply* reply)
+{
+    if (reply != d->reply)
+    {
+        return;
+    }
+
+    d->reply = 0;
+
+    if (reply->error() != QNetworkReply::NoError)
+    {
+        if (d->state != Private::OD_CREATEFOLDER)
+        {
+            emit signalBusy(false);
+            QMessageBox::critical(QApplication::activeWindow(),
+                                  i18n("Error"), reply->errorString());
+
+            reply->deleteLater();
+            return;
+        }
+    }
+
+    d->buffer.append(reply->readAll());
+
+    switch (d->state)
+    {
+        case Private::OD_LISTFOLDERS:
+            qCDebug(DIGIKAM_WEBSERVICES_LOG) << "In TW_LISTFOLDERS";
+            parseResponseListFolders(d->buffer);
+            break;
+        case Private::OD_CREATEFOLDER:
+            qCDebug(DIGIKAM_WEBSERVICES_LOG) << "In TW_CREATEFOLDER";
+            parseResponseCreateFolder(d->buffer);
+            break;
+        case Private::OD_ADDPHOTO:
+            qCDebug(DIGIKAM_WEBSERVICES_LOG) << "In TW_ADDPHOTO";
+            parseResponseAddPhoto(d->buffer);
+            break;
+        case Private::OD_USERNAME:
+            qCDebug(DIGIKAM_WEBSERVICES_LOG) << "In TW_USERNAME";
+            parseResponseUserName(d->buffer);
+            break;
+        default:
+            break;
+    }
+
+    reply->deleteLater();
+}
+void TwTalker::parseResponseAddPhoto(const QByteArray& data)
+{
+    QJsonDocument doc      = QJsonDocument::fromJson(data);
+    QJsonObject jsonObject = doc.object();
+    bool success           = jsonObject.contains(QLatin1String("size"));
+    emit signalBusy(false);
+
+    if (!success)
+    {
+        emit signalAddPhotoFailed(i18n("Failed to upload photo"));
+    }
+    else
+    {
+        emit signalAddPhotoSucceeded();
+    }
+}
+void TwTalker::parseResponseUserName(const QByteArray& data)
+{
+    QJsonDocument doc      = QJsonDocument::fromJson(data);
+    qCDebug(DIGIKAM_WEBSERVICES_LOG) << "parseResponseUserName: "<<doc;
+    QString name  = doc.object()[QLatin1String("displayName")].toString();
+
+    qCDebug(DIGIKAM_WEBSERVICES_LOG) << "parseResponseUserName: "<<name;
+    emit signalBusy(false);
+    emit signalSetUserName(name);
+}
+
+void TwTalker::parseResponseListFolders(const QByteArray& data)
+{
+    QJsonParseError err;
+    QJsonDocument doc = QJsonDocument::fromJson(data, &err);
+
+    if (err.error != QJsonParseError::NoError)
+    {
+        emit signalBusy(false);
+        emit signalListAlbumsFailed(i18n("Failed to list folders"));
+        return;
+    }
+
+    QJsonObject jsonObject = doc.object();
+    //qCDebug(DIGIKAM_WEBSERVICES_LOG) << "Json: " << doc;
+    QJsonArray jsonArray   = jsonObject[QLatin1String("value")].toArray();
+
+    //qCDebug(DIGIKAM_WEBSERVICES_LOG) << "Json response: " << jsonArray;
+
+    QList<QPair<QString, QString> > list;
+    list.append(qMakePair(QLatin1String(""), QLatin1String("root")));
+
+    foreach (const QJsonValue& value, jsonArray)
+    {
+        QString path;
+        QString folderName;
+        QJsonObject folder;
+
+        QJsonObject obj = value.toObject();
+        folder       = obj[QLatin1String("folder")].toObject();
+
+        if(!folder.isEmpty()){
+          folderName    = obj[QLatin1String("name")].toString();
+          path          =    "/" + folderName;
+          qCDebug(DIGIKAM_WEBSERVICES_LOG) << "Folder Name is" << folderName;
+          list.append(qMakePair(path, folderName));
+
+        }
+    }
+
+    emit signalBusy(false);
+    emit signalListAlbumsDone(list);
+}
+
+void TwTalker::parseResponseCreateFolder(const QByteArray& data)
+{
+    QJsonDocument doc      = QJsonDocument::fromJson(data);
+    QJsonObject jsonObject = doc.object();
+    bool fail              = jsonObject.contains(QLatin1String("error"));
+
+    emit signalBusy(false);
+
+    if (fail)
+    {
+      QJsonParseError err;
+      QJsonDocument doc = QJsonDocument::fromJson(data, &err);
+      qCDebug(DIGIKAM_WEBSERVICES_LOG) << "parseResponseCreateFolder ERROR: " << \
doc; +      emit signalCreateFolderFailed(jsonObject[QLatin1String("error_summary")].toString());
 +    }
+    else
+    {
+        emit signalCreateFolderSucceeded();
+    }
+}
+
+} // namespace Digikam
diff --git a/core/utilities/assistants/webservices/twitter/twittertalker.h \
b/core/utilities/assistants/webservices/twitter/twittertalker.h new file mode 100644
index 0000000000..d108996926
--- /dev/null
+++ b/core/utilities/assistants/webservices/twitter/twittertalker.h
@@ -0,0 +1,86 @@
+#ifndef TW_TALKER_H
+#define TW_TALKER_H
+
+// Qt includes
+
+#include <QList>
+#include <QPair>
+#include <QString>
+#include <QSettings>
+#include <QNetworkReply>
+#include <QNetworkAccessManager>
+
+// Local includes
+
+#include "twitteritem.h"
+#include "o2.h"
+#include "o0globals.h"
+#include "dmetadata.h"
+#include "o1twitter.h"
+
+namespace Digikam
+{
+
+class TwTalker : public QObject
+{
+    Q_OBJECT
+
+public:
+
+    explicit TwTalker(QWidget* const parent);
+    ~TwTalker();
+
+public:
+
+    void link();
+    void unLink();
+    void getUserName();
+    bool authenticated();
+    void cancel();
+    bool addPhoto(const QString& imgPath, const QString& uploadFolder, bool rescale, \
int maxDim, int imageQuality); +    void listFolders(const QString& path = \
QString()); +    void createFolder(QString& path);
+    void setAccessToken(const QString& token);
+    QMap<QString,QString> ParseUrlParameters(const QString& url);
+
+Q_SIGNALS:
+
+    void signalBusy(bool val);
+    void signalLinkingSucceeded();
+    void signalLinkingFailed();
+    void signalSetUserName(const QString& msg);
+    void signalListAlbumsFailed(const QString& msg);
+    void signalListAlbumsDone(const QList<QPair<QString, QString> >& list);
+    void signalCreateFolderFailed(const QString& msg);
+    void signalCreateFolderSucceeded();
+    void signalAddPhotoFailed(const QString& msg);
+    void signalAddPhotoSucceeded();
+    void twitterLinkingSucceeded();
+    void twitterLinkingFailed();
+
+private Q_SLOTS:
+
+    void slotLinkingFailed();
+    void slotLinkingSucceeded();
+    void slotOpenBrowser(const QUrl& url);
+    void slotFinished(QNetworkReply* reply);
+    void slotTweetDone();
+    //void slotGetMediaId(QNetworkReply* reply);
+    void reply2finish();
+
+private:
+
+    void parseResponseUserName(const QByteArray& data);
+    void parseResponseListFolders(const QByteArray& data);
+    void parseResponseCreateFolder(const QByteArray& data);
+    void parseResponseAddPhoto(const QByteArray& data);
+
+private:
+
+    class Private;
+    Private* const d;
+};
+
+} // namespace Digikam
+
+#endif // OD_TALKER_H
diff --git a/core/utilities/assistants/webservices/twitter/twitterwidget.cpp \
b/core/utilities/assistants/webservices/twitter/twitterwidget.cpp new file mode \
100644 index 0000000000..596873fc0d
--- /dev/null
+++ b/core/utilities/assistants/webservices/twitter/twitterwidget.cpp
@@ -0,0 +1,71 @@
+/* ============================================================
+ *
+ * This file is a part of digiKam project
+ * http://www.digikam.org
+ *
+ * Date        : 2018-06-29
+ * Description : a tool to export images to Onedrive web service
+ *
+ * Copyright (C) 2013      by Pankaj Kumar <me at panks dot me>
+ * Copyright (C) 2013-2018 by Gilles Caulier <caulier dot gilles at gmail dot com>
+ *
+ * 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, 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.
+ *
+ * ============================================================ */
+
+ #include "twitterwidget.h"
+
+// Qt includes
+
+#include <QLabel>
+#include <QGroupBox>
+
+// Local includes
+
+namespace Digikam
+{
+
+TwWidget::TwWidget(QWidget* const parent,
+                   DInfoInterface* const iface,
+                   const QString& toolName)
+    : WSSettingsWidget(parent, iface, toolName)
+{
+    getUploadBox()->hide();
+    getSizeBox()->hide();
+}
+
+TwWidget::~TwWidget()
+{
+}
+
+void TwWidget::updateLabels(const QString& name, const QString& url)
+{
+    QString web(QLatin1String("https://www.twitter.com/"));
+
+    if (!url.isEmpty())
+        web = url;
+
+    getHeaderLbl()->setText(QString::fromLatin1(
+        "<b><h2><a href='%1'>"
+        "<font color=\"#9ACD32\">Twitter</font>"
+        "</a></h2></b>").arg(web));
+
+    if (name.isEmpty())
+    {
+        getUserNameLabel()->clear();
+    }
+    else
+    {
+        getUserNameLabel()->setText(QString::fromLatin1("<b>%1</b>").arg(name));
+    }
+}
+
+} // namespace Digikam
diff --git a/core/utilities/assistants/webservices/twitter/twitterwidget.h \
b/core/utilities/assistants/webservices/twitter/twitterwidget.h new file mode 100644
index 0000000000..f8ec02e286
--- /dev/null
+++ b/core/utilities/assistants/webservices/twitter/twitterwidget.h
@@ -0,0 +1,68 @@
+/* ============================================================
+ *
+ * This file is a part of digiKam project
+ * http://www.digikam.org
+ *
+ * Date        : 2018-06-29
+ * Description : a tool to export images to Onedrive web service
+ *
+ * Copyright (C) 2013      by Pankaj Kumar <me at panks dot me>
+ * Copyright (C) 2013-2018 by Gilles Caulier <caulier dot gilles at gmail dot com>
+ *
+ * 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, 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.
+ *
+ * ============================================================ */
+
+#ifndef DIGIKAM_TW_WIDGET_H
+#define DIGIKAM_TW_WIDGET_H
+
+// Qt includes
+
+#include <QWidget>
+
+//local includes
+
+#include "wssettingswidget.h"
+#include "dinfointerface.h"
+
+namespace Digikam
+{
+
+class TwWidget : public WSSettingsWidget
+{
+    Q_OBJECT
+
+public:
+
+    explicit TwWidget(QWidget* const parent,
+                      DInfoInterface* const iface,
+                      const QString& toolName);
+    ~TwWidget();
+
+    void updateLabels(const QString& name = QString(),
+                      const QString& url = QString()) Q_DECL_OVERRIDE;
+
+Q_SIGNALS:
+
+    void reloadAlbums(long long userID);
+
+private Q_SLOTS:
+
+    //void slotReloadAlbumsRequest();
+
+private:
+
+    friend class TwWindow;
+};
+
+} // namespace Digikam
+
+#endif // DIGIKAM_TW_WIDGET_H
diff --git a/core/utilities/assistants/webservices/twitter/twitterwindow.cpp \
b/core/utilities/assistants/webservices/twitter/twitterwindow.cpp new file mode \
100644 index 0000000000..788de49603
--- /dev/null
+++ b/core/utilities/assistants/webservices/twitter/twitterwindow.cpp
@@ -0,0 +1,449 @@
+#include "twitterwindow.h"
+
+// Qt includes
+
+#include <QWindow>
+#include <QSpinBox>
+#include <QCheckBox>
+#include <QMessageBox>
+#include <QCloseEvent>
+
+// KDE includes
+
+#include <klocalizedstring.h>
+#include <kconfig.h>
+#include <kwindowconfig.h>
+
+// Local includes
+
+#include "digikam_debug.h"
+#include "dimageslist.h"
+#include "digikam_version.h"
+#include "twittertalker.h"
+#include "twitteritem.h"
+#include "twitternewalbumdlg.h"
+#include "twitterwidget.h"
+
+namespace Digikam
+{
+
+class TwWindow::Private
+{
+public:
+
+    explicit Private()
+    {
+        imagesCount = 0;
+        imagesTotal = 0;
+        widget      = 0;
+        albumDlg    = 0;
+        talker      = 0;
+    }
+
+    unsigned int   imagesCount;
+    unsigned int   imagesTotal;
+
+    TwWidget*      widget;
+    TwNewAlbumDlg* albumDlg;
+    TwTalker*      talker;
+
+    QString        currentAlbumName;
+    QList<QUrl>    transferQueue;
+};
+
+
+TwWindow::TwWindow(DInfoInterface* const iface,
+                   QWidget* const /*parent*/)
+    : WSToolDialog(0),
+      d(new Private)
+{
+    d->widget      = new TwWidget(this, iface, QLatin1String("Twitter"));
+
+    d->widget->imagesList()->setIface(iface);
+
+    setMainWidget(d->widget);
+    setModal(false);
+    setWindowTitle(i18n("Export to Twitter"));
+
+    startButton()->setText(i18n("Start Upload"));
+    startButton()->setToolTip(i18n("Start upload to Twitter"));
+
+    d->widget->setMinimumSize(700, 500);
+
+    connect(d->widget->imagesList(), SIGNAL(signalImageListChanged()),
+            this, SLOT(slotImageListChanged()));
+
+    connect(d->widget->getChangeUserBtn(), SIGNAL(clicked()),
+            this, SLOT(slotUserChangeRequest()));
+
+    connect(d->widget->getNewAlbmBtn(), SIGNAL(clicked()),
+            this, SLOT(slotNewAlbumRequest()));
+
+    //connect(d->widget->getReloadBtn(), SIGNAL(clicked()),
+            //this, SLOT(slotReloadAlbumsRequest()));
+
+    connect(startButton(), SIGNAL(clicked()),
+            this, SLOT(slotStartTransfer()));
+
+    d->albumDlg = new TwNewAlbumDlg(this, QLatin1String("Twitter"));
+    d->talker   = new TwTalker(this);
+
+    connect(d->talker,SIGNAL(signalBusy(bool)),
+            this,SLOT(slotBusy(bool)));
+
+    connect(d->talker,SIGNAL(signalLinkingFailed()),
+            this,SLOT(slotSignalLinkingFailed()));
+
+    connect(d->talker,SIGNAL(signalLinkingSucceeded()),
+            this,SLOT(slotSignalLinkingSucceeded()));
+
+    connect(d->talker,SIGNAL(signalSetUserName(QString)),
+            this,SLOT(slotSetUserName(QString)));
+
+    connect(d->talker,SIGNAL(signalListAlbumsFailed(QString)),
+            this,SLOT(slotListAlbumsFailed(QString)));
+
+    connect(d->talker,SIGNAL(signalListAlbumsDone(QList<QPair<QString,QString> >)),
+            this,SLOT(slotListAlbumsDone(QList<QPair<QString,QString> >)));
+
+    connect(d->talker,SIGNAL(signalCreateFolderFailed(QString)),
+            this,SLOT(slotCreateFolderFailed(QString)));
+
+    connect(d->talker,SIGNAL(signalCreateFolderSucceeded()),
+            this,SLOT(slotCreateFolderSucceeded()));
+
+    connect(d->talker,SIGNAL(signalAddPhotoFailed(QString)),
+            this,SLOT(slotAddPhotoFailed(QString)));
+
+    connect(d->talker,SIGNAL(signalAddPhotoSucceeded()),
+            this,SLOT(slotAddPhotoSucceeded()));
+
+    connect(this, SIGNAL(finished(int)),
+            this, SLOT(slotFinished()));
+
+    readSettings();
+    buttonStateChange(false);
+
+    d->talker->link();
+}
+
+TwWindow::~TwWindow()
+{
+    delete d->widget;
+    delete d->albumDlg;
+    delete d->talker;
+    delete d;
+}
+
+void TwWindow::readSettings()
+{
+    KConfig config;
+    KConfigGroup grp   = config.group("Twitter Settings");
+    d->currentAlbumName = grp.readEntry("Current Album",QString());
+    qCDebug(DIGIKAM_WEBSERVICES_LOG) << "readsettings:" << d->currentAlbumName;
+
+    if (grp.readEntry("Resize", false))
+    {
+        d->widget->getResizeCheckBox()->setChecked(true);
+        d->widget->getDimensionSpB()->setEnabled(true);
+        d->widget->getImgQualitySpB()->setEnabled(true);
+    }
+    else
+    {
+        d->widget->getResizeCheckBox()->setChecked(false);
+        d->widget->getDimensionSpB()->setEnabled(false);
+        d->widget->getImgQualitySpB()->setEnabled(false);
+    }
+
+    d->widget->getDimensionSpB()->setValue(grp.readEntry("Maximum Width",  1600));
+    d->widget->getImgQualitySpB()->setValue(grp.readEntry("Image Quality", 90));
+
+    KConfigGroup dialogGroup = config.group("Twitter Export Dialog");
+
+    winId();
+    KWindowConfig::restoreWindowSize(windowHandle(), dialogGroup);
+    resize(windowHandle()->size());
+}
+
+void TwWindow::writeSettings()
+{
+    KConfig config;
+    KConfigGroup grp = config.group("Onedrive Settings");
+
+    grp.writeEntry("Current Album", d->currentAlbumName);
+    grp.writeEntry("Resize",        d->widget->getResizeCheckBox()->isChecked());
+    grp.writeEntry("Maximum Width", d->widget->getDimensionSpB()->value());
+    grp.writeEntry("Image Quality", d->widget->getImgQualitySpB()->value());
+
+    KConfigGroup dialogGroup = config.group("Twitter Export Dialog");
+    KWindowConfig::saveWindowSize(windowHandle(), dialogGroup);
+
+    config.sync();
+}
+
+void TwWindow::reactivate()
+{
+    d->widget->imagesList()->loadImagesFromCurrentSelection();
+    d->widget->progressBar()->hide();
+
+    show();
+}
+
+void TwWindow::setItemsList(const QList<QUrl>& urls)
+{
+    d->widget->imagesList()->slotAddImages(urls);
+}
+
+void TwWindow::slotBusy(bool val)
+{
+    if (val)
+    {
+        setCursor(Qt::WaitCursor);
+        d->widget->getChangeUserBtn()->setEnabled(false);
+        buttonStateChange(false);
+    }
+    else
+    {
+        setCursor(Qt::ArrowCursor);
+        d->widget->getChangeUserBtn()->setEnabled(true);
+        buttonStateChange(true);
+    }
+}
+
+void TwWindow::slotSetUserName(const QString& msg)
+{
+    d->widget->updateLabels(msg, QLatin1String(""));
+}
+
+void TwWindow::slotListAlbumsDone(const QList<QPair<QString,QString> >& list)
+{
+    d->widget->getAlbumsCoB()->clear();
+    qCDebug(DIGIKAM_WEBSERVICES_LOG) << "slotListAlbumsDone:" << list.size();
+
+    for (int i = 0 ; i < list.size() ; i++)
+    {
+        d->widget->getAlbumsCoB()->addItem(
+        QIcon::fromTheme(QLatin1String("system-users")),
+        list.value(i).second, list.value(i).first);
+        qCDebug(DIGIKAM_WEBSERVICES_LOG) << "slotListAlbumsDone:" << \
list.value(i).second << " " << list.value(i).first; +        \
qCDebug(DIGIKAM_WEBSERVICES_LOG) << "slotListAlbumsDone:" <<d->currentAlbumName; +    \
if (d->currentAlbumName == list.value(i).first) +        {
+            d->widget->getAlbumsCoB()->setCurrentIndex(i);
+        }
+    }
+
+    buttonStateChange(true);
+    d->talker->getUserName();
+}
+
+void TwWindow::slotStartTransfer()
+{
+    d->widget->imagesList()->clearProcessedStatus();
+
+    if (d->widget->imagesList()->imageUrls().isEmpty())
+    {
+        QMessageBox::critical(this, i18nc("@title:window", "Error"),
+                              i18n("No image selected. Please select which images \
should be uploaded.")); +        return;
+    }
+
+    if (!(d->talker->authenticated()))
+    {
+        QMessageBox warn(QMessageBox::Warning,
+                         i18n("Warning"),
+                         i18n("Authentication failed. Click \"Continue\" to \
authenticate."), +                         QMessageBox::Yes | QMessageBox::No);
+
+        (warn.button(QMessageBox::Yes))->setText(i18n("Continue"));
+        (warn.button(QMessageBox::No))->setText(i18n("Cancel"));
+
+        if (warn.exec() == QMessageBox::Yes)
+        {
+            d->talker->link();
+            return;
+        }
+        else
+        {
+            return;
+        }
+    }
+
+    d->transferQueue = d->widget->imagesList()->imageUrls();
+
+    if (d->transferQueue.isEmpty())
+    {
+        return;
+    }
+
+    d->currentAlbumName = \
d->widget->getAlbumsCoB()->itemData(d->widget->getAlbumsCoB()->currentIndex()).toString();
 +    qCDebug(DIGIKAM_WEBSERVICES_LOG) << "StartTransfer:" << d->currentAlbumName << \
"INDEX: " << d->widget->getAlbumsCoB()->currentIndex(); +    d->imagesTotal = \
d->transferQueue.count(); +    d->imagesCount = 0;
+
+    d->widget->progressBar()->setFormat(i18n("%v / %m"));
+    d->widget->progressBar()->setMaximum(d->imagesTotal);
+    d->widget->progressBar()->setValue(0);
+    d->widget->progressBar()->show();
+    d->widget->progressBar()->progressScheduled(i18n("Twitter export"), true, true);
+    d->widget->progressBar()->progressThumbnailChanged(QIcon(QLatin1String("twitter")).pixmap(22, \
22)); +
+    uploadNextPhoto();
+}
+
+void TwWindow::uploadNextPhoto()
+{
+    qCDebug(DIGIKAM_WEBSERVICES_LOG) << "uploadNextPhoto:" << \
d->transferQueue.count(); +
+    if (d->transferQueue.isEmpty())
+    {
+        qCDebug(DIGIKAM_WEBSERVICES_LOG) << "empty";
+        d->widget->progressBar()->progressCompleted();
+        return;
+    }
+
+    QString imgPath = d->transferQueue.first().toLocalFile();
+    QString temp = d->currentAlbumName + QLatin1String("/");
+
+    bool result = d->talker->addPhoto(imgPath,
+                                   temp,
+                                   d->widget->getResizeCheckBox()->isChecked(),
+                                   d->widget->getDimensionSpB()->value(),
+                                   d->widget->getImgQualitySpB()->value());
+
+    if (!result)
+    {
+        slotAddPhotoFailed(QLatin1String(""));
+        return;
+    }
+}
+
+void TwWindow::slotAddPhotoFailed(const QString& msg)
+{
+    if (QMessageBox::question(this, i18n("Uploading Failed"),
+                              i18n("Failed to upload photo to Twitter."
+                                   "\n%1\n"
+                                   "Do you want to continue?", msg))
+        != QMessageBox::Yes)
+    {
+        d->transferQueue.clear();
+        d->widget->progressBar()->hide();
+    }
+    else
+    {
+        d->transferQueue.pop_front();
+        d->imagesTotal--;
+        d->widget->progressBar()->setMaximum(d->imagesTotal);
+        d->widget->progressBar()->setValue(d->imagesCount);
+        uploadNextPhoto();
+    }
+}
+
+void TwWindow::slotAddPhotoSucceeded()
+{
+    // Remove photo uploaded from the list
+    d->widget->imagesList()->removeItemByUrl(d->transferQueue.first());
+    d->transferQueue.pop_front();
+    d->imagesCount++;
+    d->widget->progressBar()->setMaximum(d->imagesTotal);
+    d->widget->progressBar()->setValue(d->imagesCount);
+    uploadNextPhoto();
+}
+
+void TwWindow::slotImageListChanged()
+{
+    startButton()->setEnabled(!(d->widget->imagesList()->imageUrls().isEmpty()));
+}
+
+void TwWindow::slotNewAlbumRequest()
+{
+    if (d->albumDlg->exec() == QDialog::Accepted)
+    {
+        TwAlbum newAlbum;
+        d->albumDlg->getAlbumProperties(newAlbum);
+        qCDebug(DIGIKAM_WEBSERVICES_LOG) << "slotNewAlbumRequest:" << \
newAlbum.title; +        d->currentAlbumName = \
d->widget->getAlbumsCoB()->itemData(d->widget->getAlbumsCoB()->currentIndex()).toString();
 +        QString temp = d->currentAlbumName + newAlbum.title;
+        //d->talker->createFolder(temp);
+    }
+}
+
+/*void TwWindow::slotReloadAlbumsRequest()
+{
+  //  d->talker->listFolders();
+}*/
+
+void TwWindow::slotSignalLinkingFailed()
+{
+    slotSetUserName(QLatin1String(""));
+    d->widget->getAlbumsCoB()->clear();
+
+    if (QMessageBox::question(this, i18n("Login Failed"),
+                              i18n("Authentication failed. Do you want to try \
again?")) +        == QMessageBox::Yes)
+    {
+        d->talker->link();
+    }
+}
+
+void TwWindow::slotSignalLinkingSucceeded()
+{
+    //d->talker->listFolders();
+    emit slotBusy(false);
+}
+
+void TwWindow::slotListAlbumsFailed(const QString& msg)
+{
+    QMessageBox::critical(this, QString(), i18n("Twitter call failed:\n%1", msg));
+}
+
+void TwWindow::slotCreateFolderFailed(const QString& msg)
+{
+    QMessageBox::critical(this, QString(), i18n("Twitter call failed:\n%1", msg));
+}
+
+void TwWindow::slotCreateFolderSucceeded()
+{
+    //d->talker->listFolders();
+}
+
+void TwWindow::slotTransferCancel()
+{
+    d->transferQueue.clear();
+    d->widget->progressBar()->hide();
+    d->talker->cancel();
+}
+
+void TwWindow::slotUserChangeRequest()
+{
+    slotSetUserName(QLatin1String(""));
+    d->widget->getAlbumsCoB()->clear();
+    d->talker->unLink();
+    d->talker->link();
+}
+
+void TwWindow::buttonStateChange(bool state)
+{
+    d->widget->getNewAlbmBtn()->setEnabled(state);
+    d->widget->getReloadBtn()->setEnabled(state);
+    startButton()->setEnabled(state);
+}
+
+void TwWindow::slotFinished()
+{
+    writeSettings();
+    d->widget->imagesList()->listView()->clear();
+}
+
+void TwWindow::closeEvent(QCloseEvent* e)
+{
+    if (!e)
+    {
+        return;
+    }
+
+    slotFinished();
+    e->accept();
+}
+
+} // namespace Digikam
diff --git a/core/utilities/assistants/webservices/twitter/twitterwindow.h \
b/core/utilities/assistants/webservices/twitter/twitterwindow.h new file mode 100644
index 0000000000..80ef48c34c
--- /dev/null
+++ b/core/utilities/assistants/webservices/twitter/twitterwindow.h
@@ -0,0 +1,98 @@
+/* ============================================================
+ *
+ * This file is a part of digiKam project
+ * http://www.digikam.org
+ *
+ * Date        : 2018-06-29
+ * Description : a tool to export images to Onedrive web service
+ *
+ * Copyright (C) 2013      by Pankaj Kumar <me at panks dot me>
+ * Copyright (C) 2013-2018 by Gilles Caulier <caulier dot gilles at gmail dot com>
+ *
+ * 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, 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.
+ *
+ * ============================================================ */
+
+ #ifndef DIGIKAM_TW_WINDOW_H
+ #define DIGIKAM_TW_WINDOW_H
+
+ // Qt includes
+
+ #include <QList>
+
+ // Local includes
+
+ #include "digikam_export.h"
+ #include "dinfointerface.h"
+ #include "wstooldialog.h"
+
+ class QCloseEvent;
+ class QUrl;
+
+ namespace Digikam
+ {
+
+ class TwAlbum;
+
+ class DIGIKAM_EXPORT TwWindow : public WSToolDialog
+ {
+     Q_OBJECT
+
+   public:
+
+      explicit TwWindow(DInfoInterface* const iface, QWidget* const parent);
+      ~TwWindow();
+
+      void reactivate();
+
+      void setItemsList(const QList<QUrl>& urls);
+
+  private:
+
+      void readSettings();
+      void writeSettings();
+
+      void uploadNextPhoto();
+
+      void buttonStateChange(bool state);
+      void closeEvent(QCloseEvent*) Q_DECL_OVERRIDE;
+
+  private Q_SLOTS:
+
+      void slotImageListChanged();
+      void slotUserChangeRequest();
+      void slotNewAlbumRequest();
+      //void slotReloadAlbumsRequest();
+      void slotStartTransfer();
+
+      void slotBusy(bool);
+      void slotSignalLinkingFailed();
+      void slotSignalLinkingSucceeded();
+      void slotSetUserName(const QString& msg);
+      void slotListAlbumsFailed(const QString& msg);
+      void slotListAlbumsDone(const QList<QPair<QString, QString> >& list);
+      void slotCreateFolderFailed(const QString& msg);
+      void slotCreateFolderSucceeded();
+      void slotAddPhotoFailed(const QString& msg);
+      void slotAddPhotoSucceeded();
+      void slotTransferCancel();
+
+      void slotFinished();
+
+  private:
+
+      class Private;
+      Private* const d;
+  };
+
+  } // namespace Digikam
+
+  #endif // TW_WINDOW_H


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic