diff options
Diffstat (limited to 'src/sync')
30 files changed, 3891 insertions, 0 deletions
diff --git a/src/sync/ftpsynchandler.cpp b/src/sync/ftpsynchandler.cpp new file mode 100644 index 00000000..ad845d09 --- /dev/null +++ b/src/sync/ftpsynchandler.cpp @@ -0,0 +1,289 @@ +/* ============================================================ +* +* This file is a part of the rekonq project +* +* Copyright (C) 2011 by Andrea Diamantini <adjam7 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 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/>. +* +* ============================================================ */ + + +// Self Includes +#include "ftpsynchandler.h" +#include "ftpsynchandler.moc" + +// Auto Includes +#include "rekonq.h" + +// KDE Includes +#include <KStandardDirs> +#include <klocalizedstring.h> + +#include <KIO/Job> + + +FTPSyncHandler::FTPSyncHandler(QObject *parent) + : SyncHandler(parent) +{ + kDebug() << "creating FTP handler..."; +} + + +void FTPSyncHandler::initialLoadAndCheck() +{ + if (!ReKonfig::syncEnabled()) + { + _firstTimeSynced = false; + return; + } + + // Bookmarks + if (ReKonfig::syncBookmarks()) + { + _remoteBookmarksUrl = QUrl(); + _remoteBookmarksUrl.setHost(ReKonfig::syncHost()); + _remoteBookmarksUrl.setScheme("ftp"); + _remoteBookmarksUrl.setUserName(ReKonfig::syncUser()); + _remoteBookmarksUrl.setPassword(ReKonfig::syncPass()); + _remoteBookmarksUrl.setPort(ReKonfig::syncPort()); + _remoteBookmarksUrl.setPath(ReKonfig::syncPath() + QL1S("/bookmarks.xml")); + + const QString bookmarksFilePath = KStandardDirs::locateLocal("data", QL1S("konqueror/bookmarks.xml")); + _localBookmarksUrl = KUrl(bookmarksFilePath); + + KIO::StatJob *job = KIO::stat(_remoteBookmarksUrl, KIO::StatJob::DestinationSide, 0, KIO::HideProgressInfo); + connect(job, SIGNAL(finished(KJob*)), this, SLOT(onBookmarksStatFinished(KJob*))); + } + + // History + if (ReKonfig::syncHistory()) + { + _remoteHistoryUrl = QUrl(); + _remoteHistoryUrl.setHost(ReKonfig::syncHost()); + _remoteHistoryUrl.setScheme("ftp"); + _remoteHistoryUrl.setUserName(ReKonfig::syncUser()); + _remoteHistoryUrl.setPassword(ReKonfig::syncPass()); + _remoteHistoryUrl.setPort(ReKonfig::syncPort()); + _remoteHistoryUrl.setPath(ReKonfig::syncPath() + QL1S("/history")); + + const QString historyFilePath = KStandardDirs::locateLocal("appdata", "history"); + _localHistoryUrl = KUrl(historyFilePath); + + KIO::StatJob *job = KIO::stat(_remoteHistoryUrl, KIO::StatJob::DestinationSide, 0, KIO::HideProgressInfo); + connect(job, SIGNAL(finished(KJob*)), this, SLOT(onHistoryStatFinished(KJob*))); + } + + // Passwords + if (ReKonfig::syncPasswords()) + { + _remotePasswordsUrl = QUrl(); + _remotePasswordsUrl.setHost(ReKonfig::syncHost()); + _remotePasswordsUrl.setScheme("ftp"); + _remotePasswordsUrl.setUserName(ReKonfig::syncUser()); + _remotePasswordsUrl.setPassword(ReKonfig::syncPass()); + _remotePasswordsUrl.setPort(ReKonfig::syncPort()); + _remotePasswordsUrl.setPath(ReKonfig::syncPath() + QL1S("/kdewallet.kwl")); + + const QString passwordsFilePath = KStandardDirs::locateLocal("data", QL1S("kwallet/kdewallet.kwl")); + _localPasswordsUrl = KUrl(passwordsFilePath); + + KIO::StatJob *job = KIO::stat(_remotePasswordsUrl, KIO::StatJob::DestinationSide, 0, KIO::HideProgressInfo); + connect(job, SIGNAL(finished(KJob*)), this, SLOT(onPasswordsStatFinished(KJob*))); + } +} + + +bool FTPSyncHandler::syncRelativeEnabled(bool check) +{ + if (!ReKonfig::syncEnabled()) + return false; + + if (!_firstTimeSynced) + return false; + + return check; +} + + +// --------------------------------------------------------------------------------------- + + +void FTPSyncHandler::syncBookmarks() +{ + kDebug() << "syncing now..."; + + if (!syncRelativeEnabled(ReKonfig::syncBookmarks())) + return; + + KIO::Job *job = KIO::file_copy(_localBookmarksUrl, _remoteBookmarksUrl, -1, KIO::HideProgressInfo | KIO::Overwrite); + connect(job, SIGNAL(finished(KJob*)), this, SLOT(onBookmarksSyncFinished(KJob*))); +} + + +void FTPSyncHandler::onBookmarksStatFinished(KJob *job) +{ + if (job->error()) + { + if (job->error() == KIO::ERR_DOES_NOT_EXIST) + { + KIO::Job *job = KIO::file_copy(_localBookmarksUrl, _remoteBookmarksUrl, -1, KIO::HideProgressInfo | KIO::Overwrite); + connect(job, SIGNAL(finished(KJob*)), this, SLOT(onBookmarksSyncFinished(KJob*))); + + emit syncStatus(Rekonq::Bookmarks, true, i18n("Remote bookmarks file does NOT exists. Exporting local copy...")); + _firstTimeSynced = true; + } + else + { + emit syncStatus(Rekonq::Bookmarks, false, job->errorString()); + } + } + else + { + KIO::Job *job = KIO::file_copy(_remoteBookmarksUrl, _localBookmarksUrl, -1, KIO::HideProgressInfo | KIO::Overwrite); + connect(job, SIGNAL(finished(KJob*)), this, SLOT(onBookmarksSyncFinished(KJob*))); + + emit syncStatus(Rekonq::Bookmarks, true, i18n("Remote bookmarks file exists! Syncing local copy...")); + _firstTimeSynced = true; + } +} + + +void FTPSyncHandler::onBookmarksSyncFinished(KJob *job) +{ + if (job->error()) + { + emit syncStatus(Rekonq::Bookmarks, false, job->errorString()); + emit syncBookmarksFinished(false); + return; + } + + emit syncBookmarksFinished(true); +} + + +// --------------------------------------------------------------------------------------- + + +void FTPSyncHandler::syncHistory() +{ + kDebug() << "syncing now..."; + + if (!syncRelativeEnabled(ReKonfig::syncHistory())) + return; + + KIO::Job *job = KIO::file_copy(_localHistoryUrl, _remoteHistoryUrl, -1, KIO::HideProgressInfo | KIO::Overwrite); + connect(job, SIGNAL(finished(KJob*)), this, SLOT(onHistorySyncFinished(KJob*))); +} + + +void FTPSyncHandler::onHistoryStatFinished(KJob *job) +{ + if (job->error()) + { + if (job->error() == KIO::ERR_DOES_NOT_EXIST) + { + KIO::Job *job = KIO::file_copy(_localHistoryUrl, _remoteHistoryUrl, -1, KIO::HideProgressInfo | KIO::Overwrite); + connect(job, SIGNAL(finished(KJob*)), this, SLOT(onHistorySyncFinished(KJob*))); + + emit syncStatus(Rekonq::History, true, i18n("Remote history file does NOT exists. Exporting local copy...")); + _firstTimeSynced = true; + } + else + { + emit syncStatus(Rekonq::History, false, job->errorString()); + } + } + else + { + KIO::Job *job = KIO::file_copy(_remoteHistoryUrl, _localHistoryUrl, -1, KIO::HideProgressInfo | KIO::Overwrite); + connect(job, SIGNAL(finished(KJob*)), this, SLOT(onHistorySyncFinished(KJob*))); + + emit syncStatus(Rekonq::History, true, i18n("Remote history file exists! Syncing local copy...")); + _firstTimeSynced = true; + } +} + + +void FTPSyncHandler::onHistorySyncFinished(KJob *job) +{ + if (job->error()) + { + emit syncStatus(Rekonq::History, false, job->errorString()); + emit syncHistoryFinished(false); + return; + } + + emit syncHistoryFinished(true); +} + + +// --------------------------------------------------------------------------------------- + + +void FTPSyncHandler::syncPasswords() +{ + kDebug() << "syncing now..."; + + if (!syncRelativeEnabled(ReKonfig::syncPasswords())) + return; + + KIO::Job *job = KIO::file_copy(_localPasswordsUrl, _remotePasswordsUrl, -1, KIO::HideProgressInfo | KIO::Overwrite); + connect(job, SIGNAL(finished(KJob*)), this, SLOT(onPasswordsSyncFinished(KJob*))); +} + + +void FTPSyncHandler::onPasswordsStatFinished(KJob *job) +{ + if (job->error()) + { + if (job->error() == KIO::ERR_DOES_NOT_EXIST) + { + KIO::Job *job = KIO::file_copy(_localPasswordsUrl, _remotePasswordsUrl, -1, KIO::HideProgressInfo | KIO::Overwrite); + connect(job, SIGNAL(finished(KJob*)), this, SLOT(onPasswordsSyncFinished(KJob*))); + + emit syncStatus(Rekonq::Passwords, true, i18n("Remote passwords file does NOT exists. Exporting local copy...")); + _firstTimeSynced = true; + } + else + { + emit syncStatus(Rekonq::Passwords, false, job->errorString()); + } + } + else + { + KIO::Job *job = KIO::file_copy(_remotePasswordsUrl, _localPasswordsUrl, -1, KIO::HideProgressInfo | KIO::Overwrite); + connect(job, SIGNAL(finished(KJob*)), this, SLOT(onPasswordsSyncFinished(KJob*))); + + emit syncStatus(Rekonq::Passwords, true, i18n("Remote passwords file exists! Syncing local copy...")); + _firstTimeSynced = true; + } +} + + +void FTPSyncHandler::onPasswordsSyncFinished(KJob *job) +{ + if (job->error()) + { + emit syncStatus(Rekonq::Passwords, false, job->errorString()); + emit syncPasswordsFinished(false); + return; + } + + emit syncPasswordsFinished(true); +} diff --git a/src/sync/ftpsynchandler.h b/src/sync/ftpsynchandler.h new file mode 100644 index 00000000..2cb1227a --- /dev/null +++ b/src/sync/ftpsynchandler.h @@ -0,0 +1,82 @@ +/* ============================================================ +* +* This file is a part of the rekonq project +* +* Copyright (C) 2011 by Andrea Diamantini <adjam7 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 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 FTP_SYNC_HANDLER_H +#define FTP_SYNC_HANDLER_H + + +// Local Includes +#include "synchandler.h" + +// KDE Includes +#include <KUrl> + +// Forward Declarations +class KJob; + + +class FTPSyncHandler : public SyncHandler +{ + Q_OBJECT + +public: + FTPSyncHandler(QObject *parent = 0); + + void syncHistory(); + void syncBookmarks(); + void syncPasswords(); + + void initialLoadAndCheck(); + +private Q_SLOTS: + void onBookmarksSyncFinished(KJob *); + void onBookmarksStatFinished(KJob *); + + void onHistorySyncFinished(KJob *); + void onHistoryStatFinished(KJob *); + + void onPasswordsSyncFinished(KJob *); + void onPasswordsStatFinished(KJob *); + +Q_SIGNALS: + void syncBookmarksFinished(bool); + void syncHistoryFinished(bool); + void syncPasswordsFinished(bool); + +private: + bool syncRelativeEnabled(bool); + + QUrl _remoteBookmarksUrl; + KUrl _localBookmarksUrl; + + QUrl _remoteHistoryUrl; + KUrl _localHistoryUrl; + + QUrl _remotePasswordsUrl; + KUrl _localPasswordsUrl; +}; + +#endif // FTP_SYNC_HANDLER_H diff --git a/src/sync/googlesynchandler.cpp b/src/sync/googlesynchandler.cpp new file mode 100644 index 00000000..c2de762a --- /dev/null +++ b/src/sync/googlesynchandler.cpp @@ -0,0 +1,432 @@ +/* ============================================================ +* +* This file is a part of the rekonq project +* +* Copyright (C) 2012 by Siteshwar Vashisht <siteshwar at gmail dot com> +* Copyright (C) 2011 by Andrea Diamantini <adjam7 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 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/>. +* +* ============================================================ */ + + +// Self Includes +#include "googlesynchandler.h" +#include "googlesynchandler.moc" + +// Auto Includes +#include "rekonq.h" + +// Local Includes +#include "bookmarkmanager.h" + +// KDE Includes +#include <KStandardDirs> +#include <KLocalizedString> +#include <KBookmarkManager> + +#include <QList> +#include <QWebPage> +#include <QWebFrame> +#include <QWebElement> +#include <QUrl> +#include <QWebSettings> +#include <QNetworkAccessManager> +#include <QNetworkReply> +#include <QDomDocument> + + +GoogleSyncHandler::GoogleSyncHandler(QObject *parent) + : SyncHandler(parent) + , _mode(RECEIVE_CHANGES) + , _doLogin(false) + , _isSyncing(false) + , _reply(0) + , _requestCount(0) +{ + kDebug() << "Creating Google Bookmarks handler..."; + _webPage.settings()->setAttribute(QWebSettings::AutoLoadImages, false); + _webPage.settings()->setAttribute(QWebSettings::PrivateBrowsingEnabled, true); + connect(&_webPage, SIGNAL(loadFinished(bool)), this, SLOT(loadFinished(bool))); +} + + +void GoogleSyncHandler::initialLoadAndCheck() +{ + if (!ReKonfig::syncEnabled()) + { + _firstTimeSynced = false; + return; + } + + // Bookmarks + if (ReKonfig::syncBookmarks()) + { + _mode = RECEIVE_CHANGES; + startLogin(); + } + + if (ReKonfig::syncHistory()) + { + emit syncStatus(Rekonq::History, false, i18n("Not supported!")); + } + + if (ReKonfig::syncHistory()) + { + emit syncStatus(Rekonq::Passwords, false, i18n("Not supported!")); + } +} + + +bool GoogleSyncHandler::syncRelativeEnabled(bool check) +{ + if (!ReKonfig::syncEnabled()) + return false; + + if (!_firstTimeSynced) + return false; + + return check; +} + + +// --------------------------------------------------------------------------------------- + + +void GoogleSyncHandler::syncHistory() +{ + kDebug() << "Syncing history not supported!"; + emit syncStatus(Rekonq::History, false, i18n("Syncing history not supported!")); + emit syncHistoryFinished(false); +} + + +void GoogleSyncHandler::syncPasswords() +{ + kDebug() << "Syncing passwords not supported!"; + emit syncStatus(Rekonq::Passwords, false, i18n("Syncing passwords not supported!")); + emit syncPasswordsFinished(false); +} + + +void GoogleSyncHandler::syncBookmarks() +{ + + if (_isSyncing) + { + kDebug() << "Sync already in progress!"; + return; + } + _mode = SEND_CHANGES; + startLogin(); +} + +void GoogleSyncHandler::startLogin() +{ + if (ReKonfig::syncUser().isEmpty() || ReKonfig::syncPass().isEmpty()) + { + kDebug() << "No username or password!"; + emit syncStatus(Rekonq::Bookmarks, false, i18n("No username or password!")); + emit syncBookmarksFinished(false); + return; + } + + _isSyncing = true; + + _doLogin = true; + + kDebug() << "Loading login page..."; + _webPage.mainFrame()->load(QUrl("http://bookmarks.google.com/")); +} + +//Loading a webpage finished, what action to take is decided based on url we have loaded. +void GoogleSyncHandler::loadFinished(bool ok) +{ + kDebug() << "Load Finished" << ok; + if (!ok) + { + kDebug() << "Error loading: " << _webPage.mainFrame()->url(); + emit syncStatus(Rekonq::Bookmarks, false, i18n("Error loading: " + _webPage.mainFrame()->url().toEncoded())); + + _isSyncing = false; + return; + } + + kDebug() << _webPage.mainFrame()->url(); + kDebug() << "Path : " << _webPage.mainFrame()->url().path(); + + QString path = _webPage.mainFrame()->url().path(); + + if (path == "/ServiceLogin" && _doLogin == true) + { + // Let's login to our Google account + QWebFrame *frame = _webPage.mainFrame(); + + QWebElement email = frame->findFirstElement("#Email"); + QWebElement passwd = frame->findFirstElement("#Passwd"); + QWebElement form = frame->findFirstElement("#gaia_loginform"); + + email.setAttribute("value", ReKonfig::syncUser()); + passwd.setAttribute("value", ReKonfig::syncPass()); + form.evaluateJavaScript("this.submit();"); + emit syncStatus(Rekonq::Bookmarks, true, i18n("Signing in...")); + + // Login only once + _doLogin = false; + } + else if (path == "/bookmarks/") + { + // We get to this page after successful login, let's fetch the bookmark list in Xml format. + QNetworkAccessManager *qnam = _webPage.networkAccessManager(); + QNetworkRequest request; + request.setUrl(QUrl("http://www.google.com/bookmarks/?output=xml")); + _reply = qnam->get(request); + emit syncStatus(Rekonq::Bookmarks, true, i18n("Fetching bookmarks from server...")); + connect(_reply, SIGNAL(finished()), this, SLOT(fetchingBookmarksFinished())); + } + else if (path == "/ServiceLoginAuth") + { + emit syncStatus(Rekonq::Bookmarks, false, i18n("Login failed!")); + _isSyncing = false; + } + else if (path == "/bookmarks/mark") + { + QWebFrame *frame = _webPage.mainFrame(); + + QString sigKey = frame->findFirstElement("input[name=sig]").attribute("value"); + kDebug() << "Signature Key is : " << sigKey; + + QNetworkAccessManager *qnam = _webPage.networkAccessManager(); + + if (!_bookmarksToDelete.isEmpty()) + { + + for (QSet<QString>::const_iterator iter = _bookmarksToDelete.constBegin(); iter != _bookmarksToDelete.end(); ++iter) + { + QNetworkRequest request; + request.setUrl(QUrl("https://www.google.com/bookmarks/mark?dlq=" + *iter + "&sig=" + sigKey)); + + kDebug() << "Delete url is : " << request.url(); + QNetworkReply *r = qnam->get(request); + connect(r, SIGNAL(finished()), this, SLOT(updateBookmarkFinished())); + ++_requestCount; + } + } + + if (!_bookmarksToAdd.isEmpty()) + { + emit syncStatus(Rekonq::Bookmarks, true, i18n("Adding bookmarks on server...")); + for (QSet<KUrl>::const_iterator iter = _bookmarksToAdd.constBegin(); iter != _bookmarksToAdd.end(); ++iter) + { + KBookmark bookmark = BookmarkManager::self()->bookmarkForUrl(*iter); + QByteArray postData; + postData.append("bkmk=" + QUrl::toPercentEncoding(bookmark.url().url().toUtf8())); + postData.append("&title=" + QUrl::toPercentEncoding(bookmark.text().toUtf8())); + postData.append("&annotation="); + postData.append("&labels="); + postData.append("&prev=/lookup"); + postData.append("&sig=" + sigKey.toUtf8()); + + QNetworkRequest request; + request.setUrl(QUrl("https://www.google.com/bookmarks/mark?sig=" + sigKey + "&btnA")); + request.setHeader(QNetworkRequest::ContentTypeHeader, "application/x-www-form-urlencoded"); + kDebug() << "Url: " << request.url(); + kDebug() << "Post data is :" << postData; + QNetworkReply *r = qnam->post(request, postData); + connect(r, SIGNAL(finished()), this, SLOT(updateBookmarkFinished())); + ++_requestCount; + } + } + + _bookmarksToDelete.clear(); + _bookmarksToAdd.clear(); + + } + else if (path == "/Logout") + { + //Session finished + emit syncStatus(Rekonq::Bookmarks, true, i18n("Done!")); + emit syncBookmarksFinished(true); + _isSyncing = false; + } + else + { + kDebug() << "Unknown Response!"; + _isSyncing = false; + } + +} + +//We received bookmarks stored on server in xml format, now take the action based on which mode we are in. +void GoogleSyncHandler::fetchingBookmarksFinished() +{ + QString data = _reply->readAll(); + + QDomDocument doc("bookmarks"); + doc.setContent(data); + + QDomNodeList bookmarksOnServer = doc.elementsByTagName("bookmark"); + emit syncStatus(Rekonq::Bookmarks, true, i18n("Reading bookmarks...")); + + BookmarkManager *manager = BookmarkManager::self(); + KBookmarkGroup root = manager->rootGroup(); + + if (_mode == RECEIVE_CHANGES) + { + + for (int i = 0; i < bookmarksOnServer.size(); ++i) + { + QString title = getChildElement(bookmarksOnServer.at(i), "title"); + QString url = getChildElement(bookmarksOnServer.at(i), "url"); + + KBookmark bookmark = manager->bookmarkForUrl(KUrl(url)); + if (bookmark.isNull()) + { + //Add bookmark + kDebug() << "Add bookmark"; + emit syncStatus(Rekonq::Bookmarks, true, i18n("Adding bookmark ")); + root.addBookmark(title.isEmpty() ? url : title, KUrl(url)); + manager->manager()->emitChanged(root); + } + + } + + // After receiving changes, we compare local bookmarks with Google bookmarks and if some bookmarks exist locally but not on Google Bookmarks, we add them. + checkToAddGB(root, bookmarksOnServer); + + if (!_bookmarksToAdd.isEmpty()) + { + kDebug() << "Getting sigkey"; + _webPage.mainFrame()->load(QUrl("https://www.google.com/bookmarks/mark?op=add&hl=en")); + } + else + { + _webPage.mainFrame()->load(QUrl("https://accounts.google.com/Logout?hl=en")); + emit syncStatus(Rekonq::Bookmarks, true, i18n("Signing out...")); + } + } + else + { + checkToAddGB(root, bookmarksOnServer); + checkToDeleteGB(manager, bookmarksOnServer); + + if (!_bookmarksToAdd.isEmpty() || !_bookmarksToDelete.isEmpty()) + { + kDebug() << "Getting sigkey"; + _webPage.mainFrame()->load(QUrl("https://www.google.com/bookmarks/mark?op=add&hl=en")); + } + else + { + _webPage.mainFrame()->load(QUrl("https://accounts.google.com/Logout?hl=en")); + emit syncStatus(Rekonq::Bookmarks, true, i18n("Signing out...")); + } + } + + _reply->deleteLater(); +} + +//Get value of a child element of a dom node +QString GoogleSyncHandler::getChildElement(const QDomNode &node, QString name) +{ + QDomNodeList nodes = node.childNodes(); + + for (int j = 0; j < nodes.size(); ++j) + { + QDomElement element = nodes.at(j).toElement(); + + if (nodes.at(j).nodeName() == name) + { + //kDebug() << "Url : " << element.text(); + return element.text(); + } + } + return NULL; +} + +//This method checks whether we have any other bookmarks than the ones which exist on the server +void GoogleSyncHandler::checkToAddGB(const KBookmarkGroup &root, const QDomNodeList &bookmarksOnServer) +{ + KBookmark current = root.first(); + + while (!current.isNull()) + { + kDebug() << "Checking Url to add on Google Bookmarks: " << current.url(); + bool found = false; + for (int i = 0; i < bookmarksOnServer.count(); ++i) + { + if (current.isGroup()) + { + kDebug() << "Checking group" << current.text(); + checkToAddGB(current.toGroup(), bookmarksOnServer); + //skip adding a blank in _bookmarksToAdd + found = true; + break; + } + else if (current.url().url() == getChildElement(bookmarksOnServer.at(i), "url")) + { + found = true; + } + } + + if (!found) + { + kDebug() << "Adding to Google Bookmarks: " << current.url().url(); + _bookmarksToAdd.insert(current.url()); + } + current = root.next(current); + } +} + +//Check whether we need to delete bookmarks while sending changes to Google Bookmarks +void GoogleSyncHandler::checkToDeleteGB(BookmarkManager *manager, const QDomNodeList &bookmarksOnServer) +{ + + for (int i = 0; i < bookmarksOnServer.count(); ++i) + { + QString url = getChildElement(bookmarksOnServer.at(i), "url"); + + KBookmark result = manager->bookmarkForUrl(KUrl(url)); + if (result.isNull()) + { + kDebug() << "Deleting from Google Bookmarks: " << url; + _bookmarksToDelete.insert(getChildElement(bookmarksOnServer.at(i), "id")); + } + } + +} + + +//Added or deleted a bookmark on server, check whether we succeed here, and logout when all requests are done! +void GoogleSyncHandler::updateBookmarkFinished() +{ + --_requestCount; + QNetworkReply *reply = dynamic_cast<QNetworkReply*>(sender()); + if (reply->error() != QNetworkReply::NoError) + kDebug() << "Network Error while adding bookmark to server, code is: " << reply->error(); + else if (reply->attribute(QNetworkRequest::HttpStatusCodeAttribute) != 302) + kDebug() << "Unexpected reply : " << reply->readAll(); + else + kDebug() << "Success!"; + + if (_requestCount <= 0) + { + _webPage.mainFrame()->load(QUrl("https://accounts.google.com/Logout?hl=en")); + emit syncStatus(Rekonq::Bookmarks, true, i18n("Signing out...")); + } + +} diff --git a/src/sync/googlesynchandler.h b/src/sync/googlesynchandler.h new file mode 100644 index 00000000..459ce16e --- /dev/null +++ b/src/sync/googlesynchandler.h @@ -0,0 +1,86 @@ +/* ============================================================ +* +* This file is a part of the rekonq project +* +* Copyright (C) 2012 by Siteshwar Vashisht <siteshwar at gmail dot com> +* Copyright (C) 2011 by Andrea Diamantini <adjam7 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 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 GOOGLE_SYNC_HANDLER_H +#define GOOGLE_SYNC_HANDLER_H + +#include <QWebPage> + +// Local Includes +#include "synchandler.h" + +// KDE Includes +#include <KUrl> +#include <KBookmarkGroup> + +// Forward Declarations +class QNetworkReply; +class BookmarkManager; + +class GoogleSyncHandler : public SyncHandler +{ + Q_OBJECT + +public: + GoogleSyncHandler(QObject *parent = 0); + + void syncHistory(); + void syncBookmarks(); + void syncPasswords(); + + void initialLoadAndCheck(); + +private Q_SLOTS: + void loadFinished(bool); + void fetchingBookmarksFinished(); + void updateBookmarkFinished(); + +Q_SIGNALS: + void syncBookmarksFinished(bool); + void syncHistoryFinished(bool); + void syncPasswordsFinished(bool); + +private: + bool syncRelativeEnabled(bool); + void startLogin(); + void checkToAddGB(const KBookmarkGroup &root, const QDomNodeList &); + void checkToDeleteGB(BookmarkManager *, const QDomNodeList &); + QString getChildElement(const QDomNode &node, QString name); + void checkRequestCount(); + + enum {SEND_CHANGES, RECEIVE_CHANGES} _mode; + QUrl _remoteBookmarksUrl; + bool _doLogin; + bool _isSyncing; + QWebPage _webPage; + QNetworkReply *_reply; + QSet<KUrl> _bookmarksToAdd; + QSet<QString> _bookmarksToDelete; + int _requestCount; +}; + +#endif // GOOGLE_SYNC_HANDLER_H diff --git a/src/sync/operasynchandler.cpp b/src/sync/operasynchandler.cpp new file mode 100644 index 00000000..841f7c11 --- /dev/null +++ b/src/sync/operasynchandler.cpp @@ -0,0 +1,916 @@ +/* ============================================================ +* +* This file is a part of the rekonq project +* +* Copyright (C) 2012 by Siteshwar Vashisht <siteshwar at gmail dot com> +* Copyright (C) 2011 by Andrea Diamantini <adjam7 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 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/>. +* +* ============================================================ */ + + +// Self Includes +#include "operasynchandler.h" +#include "operasynchandler.moc" + +// Auto Includes +#include "rekonq.h" + +// Local Includes +#include "bookmarkmanager.h" + +// KDE Includes +#include <KStandardDirs> +#include <klocalizedstring.h> +#include <kbookmarkmanager.h> + + +#include <QList> +#include <QWebPage> +#include <QWebFrame> +#include <QWebElement> +#include <QUrl> +#include <QWebSettings> +#include <QNetworkAccessManager> +#include <QNetworkReply> +#include <QDomDocument> + + +OperaSyncHandler::OperaSyncHandler(QObject *parent) + : SyncHandler(parent) + , _mode(RECEIVE_CHANGES) + , _doLogin(false) + , _requestCount(0) + , _isSyncing(false) +{ + kDebug() << "Creating Opera Bookmarks handler..."; + _webPage.settings()->setAttribute(QWebSettings::AutoLoadImages, false); + _webPage.settings()->setAttribute(QWebSettings::PrivateBrowsingEnabled, true); + connect(&_webPage, SIGNAL(loadFinished(bool)), this, SLOT(loadFinished(bool))); + + _qoauth.setConsumerKey("zCuj9aUcehaHsfKtcHcg2YYLX42CkxDX"); + _qoauth.setConsumerSecret("xApuyHdDd9DSbTXLDRXuZzwKI2lOYSsl"); +} + + +void OperaSyncHandler::initialLoadAndCheck() +{ + if (!ReKonfig::syncEnabled()) + { + _firstTimeSynced = false; + return; + } + + // Bookmarks + if (ReKonfig::syncBookmarks()) + { + _mode = RECEIVE_CHANGES; + startLogin(); + } + + if (ReKonfig::syncHistory()) + { + emit syncStatus(Rekonq::History, false, i18n("Not supported!")); + } + + if (ReKonfig::syncHistory()) + { + emit syncStatus(Rekonq::Passwords, false, i18n("Not supported!")); + } +} + + +bool OperaSyncHandler::syncRelativeEnabled(bool check) +{ + if (!ReKonfig::syncEnabled()) + return false; + + if (!_firstTimeSynced) + return false; + + return check; +} + + +// --------------------------------------------------------------------------------------- + + +void OperaSyncHandler::syncHistory() +{ + kDebug() << "Syncing history not supported!"; + emit syncStatus(Rekonq::History, false, i18n("Syncing history not supported!")); + emit syncHistoryFinished(false); +} + + +void OperaSyncHandler::syncPasswords() +{ + kDebug() << "Syncing passwords not supported!"; + emit syncStatus(Rekonq::Passwords, false, i18n("Syncing passwords not supported!")); + emit syncPasswordsFinished(false); +} + + +void OperaSyncHandler::syncBookmarks() +{ + + if (_isSyncing) + { + kDebug() << "Sync already in progress!"; + return; + } + _mode = SEND_CHANGES; + startLogin(); +} + +void OperaSyncHandler::startLogin() +{ + if (ReKonfig::syncUser().isEmpty() || ReKonfig::syncPass().isEmpty()) + { + kDebug() << "No username or password!"; + emit syncStatus(Rekonq::Bookmarks, false, i18n("No username or password!")); + emit syncBookmarksFinished(false); + return; + } + + _isSyncing = true; + + _doLogin = true; + + _qoauth.setRequestTimeout(20000); + _qoauth.ignoreSslErrors(); + + if (_authToken.isEmpty() || _authTokenSecret.isEmpty()) + { + // If we have not yet logged into server, we need to fetch OAuth access token and secret from server. + kDebug() << "Loading login page..."; + QOAuth::ParamMap requestMap; + requestMap.insert("oauth_callback", "oob"); + + QOAuth::ParamMap requestParam = _qoauth.requestToken("https://auth.opera.com/service/oauth/request_token", QOAuth::POST, + QOAuth::HMAC_SHA1, requestMap); + + if (_qoauth.error() != QOAuth::NoError) + { + kDebug() << "Error occured while fetching request tokens. Error code is : " << _qoauth.error(); + emit syncStatus(Rekonq::Bookmarks, false, i18n("OAuth : Error fetching request token.")); + _isSyncing = false; + return; + } + + _requestToken = requestParam.value("oauth_token"); + _requestTokenSecret = requestParam.value("oauth_token_secret"); + + kDebug() << "OAuth Request Token : " << _requestToken; + kDebug() << "OAuth Request Token Secret : " << _requestTokenSecret; + kDebug() << QUrl("https://auth.opera.com/service/oauth/authorize?oauth_token=" + QString(_requestToken) + "&oauth_callback=oob"); + + QString u = QL1S("https://auth.opera.com/service/oauth/authorize?oauth_token=") + QString(_requestToken) + QL1S("&oauth_callback=oob"); + _webPage.mainFrame()->load(QUrl(u)); + } + else + { + // We already have OAuth access token and secret, let's fetch bookmarks from server directly. + getBookmarks(); + } +} + + +// Loading a webpage finished, what action to take is decided based on url we have loaded. +void OperaSyncHandler::loadFinished(bool ok) +{ + kDebug() << "Load Finished" << ok; + if (!ok) + { + kDebug() << "Error loading: " << _webPage.mainFrame()->url(); + emit syncStatus(Rekonq::Bookmarks, false, i18n("Error loading: " + _webPage.mainFrame()->url().toEncoded())); + + _isSyncing = false; + return; + } + + QString path = _webPage.mainFrame()->url().path(); + + if (path == "/service/oauth/authorize") + { + QWebFrame *mainFrame = _webPage.mainFrame(); + QString html = mainFrame->toHtml(); + + if (_doLogin == true && html.contains("login-form")) + { + kDebug() << "Login page"; + QWebElement form = mainFrame->findFirstElement("#login-form"); + if (form.isNull()) + { + kDebug() << "form is null"; + } + + QWebElement username = form.findFirst("#username"); + QWebElement password = form.findFirst("#password"); + QWebElement button = form.findFirst("input[name=\"grant\"]"); + + username.setAttribute("value", ReKonfig::syncUser()); + password.setAttribute("value", ReKonfig::syncPass()); + + button.evaluateJavaScript("this.click();"); + emit syncStatus(Rekonq::Bookmarks, true, i18n("Signing in...")); + + _doLogin = false; + } + else if (html.contains("verifier")) + { + QOAuth::ParamMap authParams; + QWebElement authkey = mainFrame->findFirstElement("#verifier"); + QByteArray verifier = authkey.toPlainText().toUtf8(); + + kDebug() << "OAuth verifier code is : " << verifier; + authParams.insert("oauth_verifier", verifier); + + emit syncStatus(Rekonq::Bookmarks, true, i18n("OAuth : Sending verification code.")); + QOAuth::ParamMap resultParam = _qoauth.accessToken("https://auth.opera.com/service/oauth/access_token", QOAuth::POST, + _requestToken, _requestTokenSecret, QOAuth::HMAC_SHA1, authParams); + + if (_qoauth.error() != QOAuth::NoError) + { + kDebug() << "Error occurred while fetching access tokens. Error code is : " << _qoauth.error(); + emit syncStatus(Rekonq::Bookmarks, false, i18n("OAuth : Error fetching access token.")); + _isSyncing = false; + return; + } + + _authToken = resultParam.value("oauth_token"); + _authTokenSecret = resultParam.value("oauth_token_secret"); + + kDebug() << "OAuth Token : " << _authToken; + kDebug() << "OAuth Token Secret : " << _authTokenSecret; + + _requestToken.clear(); + _requestTokenSecret.clear(); + + getBookmarks(); + } + else if (_doLogin == false) + { + //Login failed + emit syncStatus(Rekonq::Bookmarks, false, i18n("Login failed!")); + kDebug() << "Login failed!"; + _isSyncing = false; + } + else + { + kDebug() << "Unknown page : " << _webPage.mainFrame()->url(); + _isSyncing = false; + } + } +} + +//Fetch all the bookmarks from server +void OperaSyncHandler::getBookmarks() +{ + emit syncStatus(Rekonq::Bookmarks, true, i18n("Fetching bookmarks from server...")); + + QOAuth::ParamMap requestMap; + + requestMap.insert("api_output", "xml"); + kDebug() << "Auth Token : " << _authToken; + kDebug() << "Auth Token Secret : " << _authTokenSecret; + + QByteArray fetchBookmarksUrl = "https://link.api.opera.com/rest/bookmark/descendants/"; + QByteArray urlParams = _qoauth.createParametersString(fetchBookmarksUrl, + QOAuth::GET, + _authToken, + _authTokenSecret, + QOAuth::HMAC_SHA1, + requestMap, + QOAuth::ParseForInlineQuery); + + QNetworkRequest request; + + fetchBookmarksUrl.append(urlParams); + //kDebug() << urlstr; + KIO::TransferJob *job = KIO::get(KUrl(fetchBookmarksUrl), KIO::Reload, KIO::HideProgressInfo); + + connect(job, SIGNAL(result(KJob*)), this, SLOT(fetchBookmarksResultSlot(KJob*))); + connect(job, SIGNAL(data(KIO::Job*, QByteArray)), this, SLOT(fetchBookmarksDataSlot(KIO::Job*, QByteArray))); +} + +void OperaSyncHandler::fetchBookmarksDataSlot(KIO::Job* job, QByteArray data) +{ + Q_UNUSED(job); + + _xmlData += data; +} + +//We have received all the bookmarks which exist on server, now we need to compare them with local bookmarks. +void OperaSyncHandler::fetchBookmarksResultSlot(KJob* job) +{ + if (job->error() != 0) + { + //Error could be because our OAuth token expired, let's reset it. + _authToken = ""; + _authTokenSecret = ""; + + _isSyncing = false; + + //Reset _xmlData for next request + _xmlData = ""; + kDebug() << "Some error!" << job->error(); + return; + } + +// kDebug() << _xmlData; + + QDomDocument doc("bookmarks"); + doc.setContent(_xmlData); + QDomNodeList responseList = doc.elementsByTagName("response"); + + KBookmarkGroup root = BookmarkManager::self()->rootGroup(); + + if (_mode == RECEIVE_CHANGES) + { + handleResponse(responseList, root); + emit syncStatus(Rekonq::Bookmarks, true, i18n("Done!")); +// _isSyncing = false; + _mode = SEND_CHANGES; + } + + + //After receiving changes from server, send changes to server. + handleResponse(responseList, root); + + QDomElement item = responseList.at(0).toElement(); + KBookmark current = root.first(); + + while (!current.isNull()) + { + if (current.isGroup()) + { + QString groupName = current.fullText(); + QDomElement child = findOperaFolder(item, groupName); + + if (child.isNull()) + { + //Add Opera group here + kDebug() << "Add group " << groupName; + KJob *job = addBookmarkFolderOnServer(current.fullText()); + _jobToGroupMap.insert(job, current.toGroup()); + } + else + { + QDomElement grandChild = getChildElement(child, "children"); + + QString id = getChildString(child, "id"); + + kDebug() << grandChild.tagName() << id; + + if (grandChild.isNull()) + { + kDebug() << "Grand child is null"; + handleLocalGroup(current.toGroup(), grandChild, id); + } + else + { + handleLocalGroup(current.toGroup(), grandChild, id); + } + } + } + + else + { + KUrl url = current.url(); + + QDomElement child = findOperaBookmark(item, url); + + if (child.isNull()) + { + //Add bookmark on server + kDebug() << "Add bookmark :" << url; + addBookmarkOnServer(current.fullText(), current.url().url()); + } + /* else + { + kDebug() << "Bookmark exists :" << url; + } + */ + } + + current = root.next(current); + } + + decreaseRequestCount(); + + _xmlData = ""; +} + +void OperaSyncHandler::createBookmarkDataSlot(KIO::Job* job, QByteArray data) +{ + Q_UNUSED(job); + Q_UNUSED(data); + + // kDebug() << data; + // _xmlData += data; +} + + +// Check whether bookmark creation was successful on server +void OperaSyncHandler::createBookmarkResultSlot(KJob* job) +{ + decreaseRequestCount(); + + if (job->error() != 0) + { + kDebug() << "Some error!" << job->error(); + return; + } +} + + +void OperaSyncHandler::createBookmarkFolderDataSlot(KIO::Job* job, QByteArray data) +{ + QByteArray &value = _jobToResponseMap[job]; + value.append(data); +} + + +// If bookmark folder (it's empty) was creted successfully on server, +// we need to add all it's children (which exists in local bookmarks) on server. +void OperaSyncHandler::createBookmarkFolderResultSlot(KJob* job) +{ + QByteArray value = _jobToResponseMap[job]; + KBookmarkGroup root = _jobToGroupMap[job]; + + _jobToResponseMap.remove(job); + _jobToGroupMap.remove(job); + + if (job->error() != 0) + { + kDebug() << "Error occured while creating bookmark folder on server. Error code : " << job->error(); + decreaseRequestCount(); + return; + } + + QDomDocument doc("new bookmark"); + doc.setContent(value); + QDomNodeList responseList = doc.elementsByTagName("response"); + + if (responseList.size() > 0) + { + QDomElement item = responseList.at(0).firstChildElement(); + + QString parentId = getIdFromResource(item); + + handleLocalGroup(root, item, parentId); + + } + + decreaseRequestCount(); +} + + +// Check whether we deleted a resource on server successfully. +void OperaSyncHandler::deleteResourceResultSlot(KJob* job) +{ + decreaseRequestCount(); + + if (job->error() != 160) + { + kDebug() << "Error occurred while deleting resource on server. Error code : " << job->error(); + return; + } +} + + +// This function is here just for debugging purpose. We don't need it's output. +void OperaSyncHandler::deleteResourceDataSlot(KIO::Job* job, QByteArray data) +{ + Q_UNUSED(job); + kDebug() << data; +} + + +// Checks whether a bookmark exists locally or not, and either add it locally or delete from server +void OperaSyncHandler::handleBookmark(const QDomElement &item, KBookmarkGroup root) +{ + QString url = getUrlFromResourceProperties(item); + QString title = getTitleFromResourceProperties(item); + QString id = getChildString(item, "id"); + + KBookmark bookmark = findLocalBookmark(root, KUrl(url)); + + if (bookmark.isNull()) + { + if (_mode == RECEIVE_CHANGES) + { + root.addBookmark(title, KUrl(url)); + BookmarkManager::self()->manager()->emitChanged(root); + } + else + { + //Delete bookmark from server + kDebug() << "Deleting bookmark from server : " << title; + deleteResourceOnServer(id); + } + } + +} + +//Traverse through all the children of a bookmark folder +void OperaSyncHandler::handleBookmarkFolder(const QDomElement &item, KBookmarkGroup &root) +{ + QDomNode child = item.firstChild(); + + while (!child.isNull()) + { + QDomNode resource = child.firstChild(); + + while (!resource.isNull()) + { + handleResource(resource, root); + resource = resource.nextSibling(); + } + child = child.nextSibling(); + } +} + +//Handle resource tag of xml replied from server +void OperaSyncHandler::handleResource(const QDomNode &item, KBookmarkGroup &root) +{ + QDomElement element = item.toElement(); + + QString itemType = getChildString(item, "item_type"); + if (itemType == "bookmark") + { + handleBookmark(element, root); + } + else if (itemType == "bookmark_folder") + { + QString title = getTitleFromResourceProperties(item.toElement()); + QString id = getChildString(item.toElement(), "id"); + if (title == "Trash") return; + + KBookmarkGroup childGroup = findLocalGroup(root, title); + + if (_mode == RECEIVE_CHANGES) + { + if (childGroup.isNull()) + { + childGroup = root.createNewFolder(title); + BookmarkManager::self()->manager()->emitChanged(root); + } + + handleBookmarkFolder(element, childGroup); + } + else + { + if (childGroup.isNull()) + { + //Delete bookmark folder on server + kDebug() << "Deleting bookmark folder from server : " << title; + deleteResourceOnServer(id); + } + else + { + handleBookmarkFolder(element, childGroup); + } + } + } +} + +//Start traversing the response received from server from <response> tag +void OperaSyncHandler::handleResponse(const QDomNodeList &responseList, KBookmarkGroup &root) +{ + if (responseList.size() > 0) + { + QDomNode item = responseList.at(0).firstChild(); + + do + { + handleResource(item, root); + item = item.nextSibling(); + } + while (!item.isNull()); + } +} + +//This method checks whether we need to add a bookmark or bookmark folder on server which exists only locally +void OperaSyncHandler::handleLocalGroup(const KBookmarkGroup &root, const QDomElement &item, QString parentId) +{ + KBookmark current = root.first(); + + while (!current.isNull()) + { + if (current.isGroup()) + { + QString groupName = current.fullText(); + QDomElement child = findOperaFolder(item, groupName); + + if (child.isNull()) + { + //Add Opera group here + KJob *job = addBookmarkFolderOnServer(current.fullText(), parentId); + _jobToGroupMap.insert(job, current.toGroup()); + } + else + { + QDomElement grandChild = getChildElement(child, "children"); + + QString id = getChildString(child, "id"); + + // FIXME: What about here??? + if (grandChild.isNull()) + { + handleLocalGroup(current.toGroup(), grandChild, id); + } + else + { + handleLocalGroup(current.toGroup(), grandChild, id); + } + } + } + else + { + KUrl url = current.url(); + + QDomElement child = findOperaBookmark(item, url); + + if (child.isNull()) + { + //Add bookmark on server + + addBookmarkOnServer(current.fullText(), current.url().url(), parentId); + } + /* else + { + kDebug() << "Bookmark exists :" << url; + } + */ + } + + current = root.next(current); + } +} + +//Add a bookmark on server +void OperaSyncHandler::addBookmarkOnServer(QString title, QString url, QString parent) +{ + QOAuth::ParamMap requestMap; + requestMap.insert("api_output", "xml"); + requestMap.insert("api_method", "create"); + requestMap.insert("item_type", "bookmark"); + requestMap.insert("title", QUrl::toPercentEncoding(title.toUtf8())); + requestMap.insert("uri", QUrl::toPercentEncoding(url.toUtf8())); + + QByteArray requestUrl = "https://link.api.opera.com/rest/bookmark/"; + + if (!parent.isNull()) + { + requestUrl.append(parent.toUtf8()); + } + + QByteArray postData = _qoauth.createParametersString(requestUrl, QOAuth::POST, _authToken, _authTokenSecret, QOAuth::HMAC_SHA1, requestMap, QOAuth::ParseForRequestContent); + + KIO::TransferJob *job = KIO::http_post(KUrl(requestUrl), postData, KIO::HideProgressInfo); + job->addMetaData("Content-Type", "application/x-www-form-urlencoded"); + + connect(job, SIGNAL(result(KJob*)), this, SLOT(createBookmarkResultSlot(KJob*))); + connect(job, SIGNAL(data(KIO::Job*, QByteArray)), this, SLOT(createBookmarkDataSlot(KIO::Job*, QByteArray))); + + ++_requestCount; +} + +//Add a bookmark folder on server +KJob *OperaSyncHandler::addBookmarkFolderOnServer(QString title, QString parent) +{ + QOAuth::ParamMap requestMap; + requestMap.insert("api_output", "xml"); + requestMap.insert("api_method", "create"); + requestMap.insert("item_type", "bookmark_folder"); + requestMap.insert("title", QUrl::toPercentEncoding(title.toUtf8())); + + QByteArray requestUrl = "https://link.api.opera.com/rest/bookmark/"; + if (!parent.isNull()) + { + requestUrl.append(parent.toUtf8()); + } + + QByteArray postData = _qoauth.createParametersString(requestUrl, QOAuth::POST, _authToken, _authTokenSecret, QOAuth::HMAC_SHA1, requestMap, QOAuth::ParseForRequestContent); + + KIO::TransferJob *job = KIO::http_post(KUrl(requestUrl), postData, KIO::HideProgressInfo); + job->addMetaData("Content-Type", "application/x-www-form-urlencoded"); + _jobToResponseMap.insert(job, ""); + + connect(job, SIGNAL(result(KJob*)), this, SLOT(createBookmarkFolderResultSlot(KJob*))); + connect(job, SIGNAL(data(KIO::Job*, QByteArray)), this, SLOT(createBookmarkFolderDataSlot(KIO::Job*, QByteArray))); + + ++_requestCount; + return job; +} + +//Resource could be either a bookmark folder or bookmark. +void OperaSyncHandler::deleteResourceOnServer(QString id) +{ + QOAuth::ParamMap requestMap; + requestMap.insert("api_method", "delete"); + + QByteArray requestUrl = "https://link.api.opera.com/rest/bookmark/"; + + if (id.isEmpty()) + { + kDebug() << "Id is empty!"; + return; + } + + requestUrl.append(id.toUtf8()); + QByteArray postData = _qoauth.createParametersString(requestUrl, QOAuth::POST, _authToken, _authTokenSecret, QOAuth::HMAC_SHA1, requestMap, QOAuth::ParseForRequestContent); + + kDebug() << "Deleting Resource : " << id; + + KIO::TransferJob *job = KIO::http_post(KUrl(requestUrl), postData, KIO::HideProgressInfo); + job->addMetaData("Content-Type", "application/x-www-form-urlencoded"); + + connect(job, SIGNAL(result(KJob*)), this, SLOT(deleteResourceResultSlot(KJob*))); + connect(job, SIGNAL(data(KIO::Job*, QByteArray)), this, SLOT(deleteResourceDataSlot(KIO::Job*, QByteArray))); + + ++_requestCount; +} + +//Get url for a bookmark from xml element of Opera bookmarks +QString OperaSyncHandler::getUrlFromResourceProperties(const QDomElement &item) +{ + if (item.tagName() != "resource") return QString(); + QDomNodeList propertiesList = item.elementsByTagName("properties"); + + if (propertiesList.size() > 0) + { + QDomElement properties = propertiesList.at(0).toElement(); + QDomNodeList uriList = properties.elementsByTagName("uri"); + if (uriList.size() > 0) + return uriList.at(0).toElement().text(); + } + + return QString(); +} + +//Get title for a bookmark or folder from xml element of Opera bookmarks +QString OperaSyncHandler::getTitleFromResourceProperties(const QDomElement &item) +{ + if (item.tagName() != "resource") return QString(); + + QDomNodeList propertiesList = item.elementsByTagName("properties"); + + if (propertiesList.size() > 0) + { + QDomElement properties = propertiesList.at(0).toElement(); + QDomNodeList titleList = properties.elementsByTagName("title"); + if (titleList.size() > 0) + return titleList.at(0).toElement().text(); + } + + return QString(); +} + +//Get id for a bookmark or folder from xml element of Opera bookmarks +QString OperaSyncHandler::getIdFromResource(const QDomElement &item) +{ + if (item.tagName() != "resource") return QString(); + + QDomNodeList idList = item.elementsByTagName("id"); + + if (idList.size() > 0) + { + return idList.at(0).toElement().text(); + } + + return QString(); +} + +//Get text of a child element of a dom node +QString OperaSyncHandler::getChildString(const QDomNode &node, const QString &name) +{ + QDomNodeList nodes = node.childNodes(); + + for (int j = 0; j < nodes.size(); ++j) + { + QDomElement element = nodes.at(j).toElement(); + + if (nodes.at(j).nodeName() == name) + { + return element.text(); + } + } + return NULL; +} + +//Get value of a child element of a dom node as an element +QDomElement OperaSyncHandler::getChildElement(const QDomNode &node, const QString &name) +{ + QDomNodeList nodes = node.childNodes(); + + for (int j = 0; j < nodes.size(); ++j) + { + QDomElement element = nodes.at(j).toElement(); + + if (nodes.at(j).nodeName() == name) + { + return element; + } + } + return QDomElement(); +} + +//Find a bookmark group in a specifiec bookmark group of client +KBookmarkGroup OperaSyncHandler::findLocalGroup(const KBookmarkGroup &root, const QString &name) +{ + KBookmark child = root.first(); + + while (!child.isNull()) + { + if (child.isGroup() && name == child.fullText()) + { + break; + } + child = root.next(child); + } + + return child.toGroup(); +} + +//Find a bookmark in a specifiec bookmark group of client +KBookmark OperaSyncHandler::findLocalBookmark(const KBookmarkGroup &root, const KUrl &url) +{ + KBookmark child = root.first(); + + while (!child.isNull()) + { + if (!child.isGroup() && url == child.url()) + { + break; + } + child = root.next(child); + } + + return child; +} + +//Find bookmark folder in xml returned by server +QDomElement OperaSyncHandler::findOperaFolder(const QDomElement &root, const QString &name) +{ + QDomElement current = root.firstChild().toElement(); + + while (!current.isNull()) + { + if ((getChildString(current, "item_type") == "bookmark_folder") && getTitleFromResourceProperties(current) == name) + break; + current = current.nextSibling().toElement(); + } + + return current; +} + +//Find bookmark in xml returned by server +QDomElement OperaSyncHandler::findOperaBookmark(const QDomElement &root, const KUrl &url) +{ + QDomElement current = root.firstChild().toElement(); + + while (!current.isNull()) + { + if ((getChildString(current, "item_type") == "bookmark") && KUrl(getUrlFromResourceProperties(current)) == url) + break; + current = current.nextSibling().toElement(); + } + + return current; +} + +/*While sending changes to server, we need to keep track of requests which have been sent to server +to check whether syncing is finished. +*/ +void OperaSyncHandler::decreaseRequestCount() +{ + if (_requestCount > 0) + { + --_requestCount; + } + + if (_requestCount <= 0) + { + emit syncStatus(Rekonq::Bookmarks, true, i18n("Done!")); + _isSyncing = false; + } +} diff --git a/src/sync/operasynchandler.h b/src/sync/operasynchandler.h new file mode 100644 index 00000000..794164c1 --- /dev/null +++ b/src/sync/operasynchandler.h @@ -0,0 +1,134 @@ +/* ============================================================ +* +* This file is a part of the rekonq project +* +* Copyright (C) 2012 by Siteshwar Vashisht <siteshwar at gmail dot com> +* Copyright (C) 2011 by Andrea Diamantini <adjam7 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 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 OPERA_SYNC_HANDLER_H +#define OPERA_SYNC_HANDLER_H + +#include <QWebPage> + +// Local Includes +#include "synchandler.h" + +// KDE Includes +#include <KUrl> +#include <KBookmarkGroup> +#include <KIO/Job> + +// Qt Includes +#include <QtOAuth/QtOAuth> + +// Forward Declarations +class QNetworkReply; +class BookmarkManager; +class QWebView; + + +class OperaSyncHandler : public SyncHandler +{ + Q_OBJECT + +public: + OperaSyncHandler(QObject *parent = 0); + + void syncHistory(); + void syncBookmarks(); + void syncPasswords(); + + void initialLoadAndCheck(); + +private Q_SLOTS: + void loadFinished(bool); + + void fetchBookmarksDataSlot(KIO::Job*, QByteArray); + void fetchBookmarksResultSlot(KJob*); + + void createBookmarkDataSlot(KIO::Job*, QByteArray); + void createBookmarkResultSlot(KJob*); + + void createBookmarkFolderDataSlot(KIO::Job*, QByteArray); + void createBookmarkFolderResultSlot(KJob*); + + void deleteResourceDataSlot(KIO::Job*, QByteArray); + void deleteResourceResultSlot(KJob*); + +Q_SIGNALS: + void syncBookmarksFinished(bool); + void syncHistoryFinished(bool); + void syncPasswordsFinished(bool); + +private: + enum {SEND_CHANGES, RECEIVE_CHANGES} _mode; + + bool syncRelativeEnabled(bool); + void startLogin(); + void getBookmarks(); + + void handleBookmark(const QDomElement &item, KBookmarkGroup root); + void handleBookmarkFolder(const QDomElement &item, KBookmarkGroup &root); + void handleResource(const QDomNode &item, KBookmarkGroup &root); + void handleResponse(const QDomNodeList &responseList, KBookmarkGroup &root); + + void handleLocalGroup(const KBookmarkGroup &root, const QDomElement &item, QString parentId); + + void addBookmarkOnServer(QString, QString, QString parent = QString()); + KJob *addBookmarkFolderOnServer(QString, QString parent = QString()); + void deleteResourceOnServer(QString id); + + static QString getUrlFromResourceProperties(const QDomElement &item); + static QString getTitleFromResourceProperties(const QDomElement &item); + static QString getIdFromResource(const QDomElement &item); + static QString getChildString(const QDomNode &node, const QString &name); + static QDomElement getChildElement(const QDomNode &node, const QString &name); + + static KBookmarkGroup findLocalGroup(const KBookmarkGroup &root, const QString &name); + static KBookmark findLocalBookmark(const KBookmarkGroup &root, const KUrl &url); + + static QDomElement findOperaFolder(const QDomElement &root, const QString &name); + static QDomElement findOperaBookmark(const QDomElement &root, const KUrl &url); + + void decreaseRequestCount(); + + + bool _doLogin; + + QWebPage _webPage; + + int _requestCount; + + bool _isSyncing; + + QOAuth::Interface _qoauth; + + QByteArray _requestToken, _requestTokenSecret; + QByteArray _authToken, _authTokenSecret; + + QByteArray _xmlData; + QMap<KJob*, QByteArray> _jobToResponseMap; + QMap<KJob*, KBookmarkGroup> _jobToGroupMap; +}; + +#endif // OPERA_SYNC_HANDLER_H diff --git a/src/sync/sync_check.ui b/src/sync/sync_check.ui new file mode 100644 index 00000000..158e1e84 --- /dev/null +++ b/src/sync/sync_check.ui @@ -0,0 +1,149 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> + <class>SyncCheck</class> + <widget class="QWidget" name="SyncCheck"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>645</width> + <height>464</height> + </rect> + </property> + <layout class="QVBoxLayout" name="verticalLayout"> + <item> + <widget class="QGroupBox" name="groupBox_2"> + <property name="title"> + <string>data</string> + </property> + <layout class="QGridLayout" name="gridLayout_2"> + <item row="0" column="0"> + <widget class="QLabel" name="label_4"> + <property name="text"> + <string>sync handler</string> + </property> + </widget> + </item> + <item row="0" column="1"> + <widget class="QLabel" name="syncLabel"> + <property name="text"> + <string>TextLabel</string> + </property> + </widget> + </item> + <item row="1" column="0"> + <widget class="QLabel" name="label_5"> + <property name="text"> + <string>Host</string> + </property> + </widget> + </item> + <item row="1" column="1"> + <widget class="QLabel" name="hostLabel"> + <property name="text"> + <string>TextLabel</string> + </property> + </widget> + </item> + </layout> + </widget> + </item> + <item> + <widget class="QGroupBox" name="groupBox"> + <property name="title"> + <string>check</string> + </property> + <layout class="QGridLayout" name="gridLayout"> + <item row="0" column="0"> + <widget class="QLabel" name="label"> + <property name="text"> + <string>Bookmarks</string> + </property> + </widget> + </item> + <item row="0" column="2"> + <widget class="QLabel" name="bkMsgLabel"> + <property name="acceptDrops"> + <bool>true</bool> + </property> + <property name="text"> + <string/> + </property> + </widget> + </item> + <item row="1" column="0"> + <widget class="QLabel" name="label_2"> + <property name="text"> + <string>History</string> + </property> + </widget> + </item> + <item row="1" column="1"> + <widget class="QLabel" name="hsLabel"> + <property name="text"> + <string/> + </property> + </widget> + </item> + <item row="1" column="2"> + <widget class="QLabel" name="hsMsgLabel"> + <property name="acceptDrops"> + <bool>true</bool> + </property> + <property name="text"> + <string/> + </property> + </widget> + </item> + <item row="2" column="0"> + <widget class="QLabel" name="label_3"> + <property name="text"> + <string>Passwords</string> + </property> + </widget> + </item> + <item row="2" column="1"> + <widget class="QLabel" name="psLabel"> + <property name="text"> + <string/> + </property> + </widget> + </item> + <item row="2" column="2"> + <widget class="QLabel" name="psMsgLabel"> + <property name="acceptDrops"> + <bool>true</bool> + </property> + <property name="text"> + <string/> + </property> + </widget> + </item> + <item row="0" column="1"> + <widget class="QLabel" name="bkLabel"> + <property name="text"> + <string/> + </property> + </widget> + </item> + </layout> + </widget> + </item> + <item> + <spacer name="verticalSpacer"> + <property name="orientation"> + <enum>Qt::Vertical</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>20</width> + <height>154</height> + </size> + </property> + </spacer> + </item> + </layout> + </widget> + <resources/> + <connections/> +</ui> diff --git a/src/sync/sync_data.ui b/src/sync/sync_data.ui new file mode 100644 index 00000000..73058357 --- /dev/null +++ b/src/sync/sync_data.ui @@ -0,0 +1,76 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> + <class>SyncData</class> + <widget class="QWidget" name="SyncData"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>378</width> + <height>369</height> + </rect> + </property> + <property name="minimumSize"> + <size> + <width>300</width> + <height>0</height> + </size> + </property> + <layout class="QVBoxLayout" name="verticalLayout_2"> + <item> + <widget class="QGroupBox" name="syncGroupBox"> + <property name="title"> + <string>sync</string> + </property> + <layout class="QVBoxLayout" name="verticalLayout"> + <item> + <widget class="QCheckBox" name="kcfg_syncBookmarks"> + <property name="enabled"> + <bool>false</bool> + </property> + <property name="text"> + <string>bookmarks</string> + </property> + </widget> + </item> + <item> + <widget class="QCheckBox" name="kcfg_syncHistory"> + <property name="enabled"> + <bool>false</bool> + </property> + <property name="text"> + <string>history</string> + </property> + </widget> + </item> + <item> + <widget class="QCheckBox" name="kcfg_syncPasswords"> + <property name="enabled"> + <bool>false</bool> + </property> + <property name="text"> + <string>passwords</string> + </property> + </widget> + </item> + </layout> + </widget> + </item> + <item> + <spacer name="verticalSpacer"> + <property name="orientation"> + <enum>Qt::Vertical</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>20</width> + <height>50</height> + </size> + </property> + </spacer> + </item> + </layout> + </widget> + <resources/> + <connections/> +</ui> diff --git a/src/sync/sync_ftp_settings.ui b/src/sync/sync_ftp_settings.ui new file mode 100644 index 00000000..fc29bd4e --- /dev/null +++ b/src/sync/sync_ftp_settings.ui @@ -0,0 +1,102 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> + <class>SyncFTPSettings</class> + <widget class="QWidget" name="SyncFTPSettings"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>400</width> + <height>300</height> + </rect> + </property> + <layout class="QVBoxLayout" name="verticalLayout"> + <item> + <widget class="QGroupBox" name="ftpGroupBox"> + <property name="title"> + <string>remote FTP host settings</string> + </property> + <layout class="QFormLayout" name="formLayout"> + <item row="0" column="0"> + <widget class="QLabel" name="label"> + <property name="text"> + <string>Server:</string> + </property> + </widget> + </item> + <item row="0" column="1"> + <widget class="KLineEdit" name="kcfg_syncHost"/> + </item> + <item row="1" column="0"> + <widget class="QLabel" name="label_2"> + <property name="text"> + <string>Username:</string> + </property> + </widget> + </item> + <item row="1" column="1"> + <widget class="KLineEdit" name="kcfg_syncUser"/> + </item> + <item row="2" column="0"> + <widget class="QLabel" name="label_3"> + <property name="text"> + <string>Password:</string> + </property> + </widget> + </item> + <item row="2" column="1"> + <widget class="KLineEdit" name="kcfg_syncPass"/> + </item> + <item row="3" column="1"> + <widget class="KLineEdit" name="kcfg_syncPath"/> + </item> + <item row="3" column="0"> + <widget class="QLabel" name="label_4"> + <property name="text"> + <string>Path:</string> + </property> + </widget> + </item> + <item row="4" column="1"> + <widget class="KIntNumInput" name="kcfg_syncPort"/> + </item> + <item row="4" column="0"> + <widget class="QLabel" name="label_5"> + <property name="text"> + <string>Port:</string> + </property> + </widget> + </item> + </layout> + </widget> + </item> + <item> + <spacer name="verticalSpacer"> + <property name="orientation"> + <enum>Qt::Vertical</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>20</width> + <height>124</height> + </size> + </property> + </spacer> + </item> + </layout> + </widget> + <customwidgets> + <customwidget> + <class>KLineEdit</class> + <extends>QLineEdit</extends> + <header>klineedit.h</header> + </customwidget> + <customwidget> + <class>KIntNumInput</class> + <extends>QWidget</extends> + <header>knuminput.h</header> + </customwidget> + </customwidgets> + <resources/> + <connections/> +</ui> diff --git a/src/sync/sync_google_settings.ui b/src/sync/sync_google_settings.ui new file mode 100644 index 00000000..d23d083b --- /dev/null +++ b/src/sync/sync_google_settings.ui @@ -0,0 +1,83 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> + <class>SyncGoogleSettings</class> + <widget class="QWidget" name="SyncGoogleSettings"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>400</width> + <height>300</height> + </rect> + </property> + <layout class="QVBoxLayout" name="verticalLayout"> + <item> + <widget class="QGroupBox" name="googleGroupBox"> + <property name="title"> + <string>Google Account Settings</string> + </property> + <layout class="QFormLayout" name="formLayout"> + <property name="fieldGrowthPolicy"> + <enum>QFormLayout::ExpandingFieldsGrow</enum> + </property> + <item row="0" column="0"> + <widget class="QLabel" name="label_2"> + <property name="text"> + <string>Username:</string> + </property> + </widget> + </item> + <item row="0" column="1"> + <widget class="KLineEdit" name="kcfg_syncUser"/> + </item> + <item row="1" column="0"> + <widget class="QLabel" name="label_3"> + <property name="text"> + <string>Password:</string> + </property> + </widget> + </item> + <item row="1" column="1"> + <widget class="KLineEdit" name="kcfg_syncPass"/> + </item> + </layout> + </widget> + </item> + <item> + <widget class="QLabel" name="infoLabel"> + <property name="styleSheet"> + <string notr="true">QLabel { color : red; }</string> + </property> + <property name="text"> + <string>Only bookmarks will be synchronized.</string> + </property> + <property name="alignment"> + <set>Qt::AlignCenter</set> + </property> + </widget> + </item> + <item> + <spacer name="verticalSpacer"> + <property name="orientation"> + <enum>Qt::Vertical</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>20</width> + <height>124</height> + </size> + </property> + </spacer> + </item> + </layout> + </widget> + <customwidgets> + <customwidget> + <class>KLineEdit</class> + <extends>QLineEdit</extends> + <header>klineedit.h</header> + </customwidget> + </customwidgets> + <resources/> + <connections/> +</ui> diff --git a/src/sync/sync_host_type.ui b/src/sync/sync_host_type.ui new file mode 100644 index 00000000..30656981 --- /dev/null +++ b/src/sync/sync_host_type.ui @@ -0,0 +1,62 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> + <class>SyncHostType</class> + <widget class="QWidget" name="SyncHostType"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>400</width> + <height>300</height> + </rect> + </property> + <layout class="QVBoxLayout" name="verticalLayout_2"> + <item> + <widget class="QCheckBox" name="kcfg_syncEnabled"> + <property name="text"> + <string>Activate sync</string> + </property> + </widget> + </item> + <item> + <widget class="QGroupBox" name="hostGroupBox"> + <property name="title"> + <string>sync host type</string> + </property> + <layout class="QVBoxLayout" name="verticalLayout"> + <item> + <widget class="QRadioButton" name="ftpRadioButton"> + <property name="text"> + <string>FTP</string> + </property> + </widget> + </item> + <item> + <widget class="QRadioButton" name="googleRadioButton"> + <property name="text"> + <string>Google Sync</string> + </property> + </widget> + </item> + <item> + <widget class="QRadioButton" name="operaRadioButton"> + <property name="text"> + <string>Opera Sync</string> + </property> + </widget> + </item> + <item> + <widget class="QRadioButton" name="nullRadioButton"> + <property name="text"> + <string>/dev/null</string> + </property> + </widget> + </item> + </layout> + </widget> + </item> + </layout> + </widget> + <resources/> + <connections/> +</ui> diff --git a/src/sync/sync_opera_settings.ui b/src/sync/sync_opera_settings.ui new file mode 100644 index 00000000..86da1cb3 --- /dev/null +++ b/src/sync/sync_opera_settings.ui @@ -0,0 +1,83 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> + <class>SyncOperaSettings</class> + <widget class="QWidget" name="SyncOperaSettings"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>400</width> + <height>300</height> + </rect> + </property> + <layout class="QVBoxLayout" name="verticalLayout"> + <item> + <widget class="QGroupBox" name="operaGroupBox"> + <property name="title"> + <string>Opera Account Settings</string> + </property> + <layout class="QFormLayout" name="formLayout"> + <property name="fieldGrowthPolicy"> + <enum>QFormLayout::ExpandingFieldsGrow</enum> + </property> + <item row="0" column="0"> + <widget class="QLabel" name="label_2"> + <property name="text"> + <string>Username:</string> + </property> + </widget> + </item> + <item row="0" column="1"> + <widget class="KLineEdit" name="kcfg_syncUser"/> + </item> + <item row="1" column="0"> + <widget class="QLabel" name="label_3"> + <property name="text"> + <string>Password:</string> + </property> + </widget> + </item> + <item row="1" column="1"> + <widget class="KLineEdit" name="kcfg_syncPass"/> + </item> + </layout> + </widget> + </item> + <item> + <widget class="QLabel" name="infoLabel"> + <property name="styleSheet"> + <string notr="true">QLabel { color : red; }</string> + </property> + <property name="text"> + <string>Only bookmarks will be synchronized.</string> + </property> + <property name="alignment"> + <set>Qt::AlignCenter</set> + </property> + </widget> + </item> + <item> + <spacer name="verticalSpacer"> + <property name="orientation"> + <enum>Qt::Vertical</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>20</width> + <height>124</height> + </size> + </property> + </spacer> + </item> + </layout> + </widget> + <customwidgets> + <customwidget> + <class>KLineEdit</class> + <extends>QLineEdit</extends> + <header>klineedit.h</header> + </customwidget> + </customwidgets> + <resources/> + <connections/> +</ui> diff --git a/src/sync/syncassistant.cpp b/src/sync/syncassistant.cpp new file mode 100644 index 00000000..7edc1f67 --- /dev/null +++ b/src/sync/syncassistant.cpp @@ -0,0 +1,52 @@ +/* ============================================================ +* +* This file is a part of the rekonq project +* +* Copyright (C) 2011-2012 by Andrea Diamantini <adjam7 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 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/>. +* +* ============================================================ */ + + +// Self Includes +#include "syncassistant.h" +#include "syncassistant.moc" + +// Local Includes +#include "synccheckwidget.h" +#include "syncdatawidget.h" +#include "synchosttypewidget.h" + +#include "syncftpsettingswidget.h" +#include "syncgooglesettingswidget.h" +#include "syncoperasettingswidget.h" + + +SyncAssistant::SyncAssistant(QWidget *parent) + : QWizard(parent) +{ + setWindowTitle(i18n("sync assistant")); + + setPage(Page_Type, new SyncHostTypeWidget(this)); + setPage(Page_FTP_Settings, new SyncFTPSettingsWidget(this)); + setPage(Page_Google_Settings, new SyncGoogleSettingsWidget(this)); + setPage(Page_Opera_Settings, new SyncOperaSettingsWidget(this)); + setPage(Page_Data, new SyncDataWidget(this)); + setPage(Page_Check, new SyncCheckWidget(this)); +} diff --git a/src/sync/syncassistant.h b/src/sync/syncassistant.h new file mode 100644 index 00000000..f373a5f8 --- /dev/null +++ b/src/sync/syncassistant.h @@ -0,0 +1,53 @@ +/* ============================================================ +* +* This file is a part of the rekonq project +* +* Copyright (C) 2011-2012 by Andrea Diamantini <adjam7 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 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 SYNC_ASSISTANT_H +#define SYNC_ASSISTANT_H + + +// KDE Includes +#include <QWizard> + + +class SyncAssistant : public QWizard +{ + Q_OBJECT + +public: + enum + { + Page_Type, + Page_FTP_Settings, + Page_Google_Settings, + Page_Opera_Settings, + Page_Data, + Page_Check + }; + + SyncAssistant(QWidget *parent = 0); +}; + +#endif diff --git a/src/sync/synccheckwidget.cpp b/src/sync/synccheckwidget.cpp new file mode 100644 index 00000000..c7ccdeb4 --- /dev/null +++ b/src/sync/synccheckwidget.cpp @@ -0,0 +1,199 @@ +/* ============================================================ +* +* This file is a part of the rekonq project +* +* Copyright (C) 2011-2012 by Andrea Diamantini <adjam7 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 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/>. +* +* ============================================================ */ + + +// Self Includes +#include "synccheckwidget.h" +#include "synccheckwidget.moc" + +// Auto Includes +#include "rekonq.h" + +// Local Includes +#include "syncassistant.h" +#include "syncmanager.h" + +// KDE Includes +#include <KStandardDirs> +#include <KIcon> + +// Qt Includes +#include <QMovie> + + +SyncCheckWidget::SyncCheckWidget(QWidget *parent) + : QWizardPage(parent) +{ + setupUi(this); +} + + +void SyncCheckWidget::initializePage() +{ + // set initial values + if (ReKonfig::syncType() == 0) + { + syncLabel->setText(i18n("FTP")); + hostLabel->setText(ReKonfig::syncHost()); + } + else if (ReKonfig::syncType() == 1) + { + syncLabel->setText(i18n("Google")); + hostLabel->setText(ReKonfig::syncHost()); + } + else if (ReKonfig::syncType() == 2) + { + syncLabel->setText(i18n("Opera")); + hostLabel->setText(ReKonfig::syncHost()); + } + else + { + syncLabel->setText(i18n("No sync")); + hostLabel->setText(i18n("none")); + } + + bkMsgLabel->setText(QString()); + hsMsgLabel->setText(QString()); + psMsgLabel->setText(QString()); + + KIcon notSyncedIcon(QL1S("dialog-cancel")); + + if (!ReKonfig::syncEnabled()) + { + bkLabel->setPixmap(notSyncedIcon.pixmap(16)); + hsLabel->setPixmap(notSyncedIcon.pixmap(16)); + psLabel->setPixmap(notSyncedIcon.pixmap(16)); + return; + } + + QString loadingGitPath = KStandardDirs::locate("appdata" , "pics/loading.mng"); + + // Now, load syncManager settings... + SyncManager::self()->loadSettings(); + + SyncHandler *h = SyncManager::self()->handler(); + + if (!h) + { + bkLabel->setPixmap(notSyncedIcon.pixmap(16)); + hsLabel->setPixmap(notSyncedIcon.pixmap(16)); + psLabel->setPixmap(notSyncedIcon.pixmap(16)); + return; + } + + connect(h, SIGNAL(syncStatus(Rekonq::SyncData, bool, QString)), this, SLOT(updateWidget(Rekonq::SyncData, bool, QString))); + + + // bookmarks + if (ReKonfig::syncBookmarks()) + { + QMovie *movie = new QMovie(loadingGitPath, QByteArray(), bkLabel); + movie->setSpeed(50); + bkLabel->setMovie(movie); + movie->start(); + } + else + { + bkLabel->setPixmap(notSyncedIcon.pixmap(16)); + } + + // history + if (ReKonfig::syncHistory()) + { + QMovie *movie = new QMovie(loadingGitPath, QByteArray(), hsLabel); + movie->setSpeed(50); + hsLabel->setMovie(movie); + movie->start(); + } + else + { + hsLabel->setPixmap(notSyncedIcon.pixmap(16)); + } + + // passwords + if (ReKonfig::syncPasswords()) + { + QMovie *movie = new QMovie(loadingGitPath, QByteArray(), psLabel); + movie->setSpeed(50); + psLabel->setMovie(movie); + movie->start(); + } + else + { + psLabel->setPixmap(notSyncedIcon.pixmap(16)); + } +} + + + + +void SyncCheckWidget::updateWidget(Rekonq::SyncData type, bool done, QString msg) +{ + KIcon doneIcon(QL1S("dialog-ok-apply")); + KIcon failIcon(QL1S("edit-delete")); + + switch (type) + { + case Rekonq::Bookmarks: + if (done) + { + bkLabel->setPixmap(doneIcon.pixmap(16)); + } + else + { + bkLabel->setPixmap(failIcon.pixmap(16)); + } + bkMsgLabel->setText(msg); + break; + + case Rekonq::History: + if (done) + { + hsLabel->setPixmap(doneIcon.pixmap(16)); + } + else + { + hsLabel->setPixmap(failIcon.pixmap(16)); + } + hsMsgLabel->setText(msg); + break; + + case Rekonq::Passwords: + if (done) + { + psLabel->setPixmap(doneIcon.pixmap(16)); + } + else + { + psLabel->setPixmap(failIcon.pixmap(16)); + } + psMsgLabel->setText(msg); + break; + + default: + // nothing to do here... + break; + }; +} diff --git a/src/sync/synccheckwidget.h b/src/sync/synccheckwidget.h new file mode 100644 index 00000000..312fe9b4 --- /dev/null +++ b/src/sync/synccheckwidget.h @@ -0,0 +1,53 @@ +/* ============================================================ +* +* This file is a part of the rekonq project +* +* Copyright (C) 2011-2012 by Andrea Diamantini <adjam7 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 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 SYNC_CHECK_WIDGET_H +#define SYNC_CHECK_WIDGET_H + + +// Rekonq Includes +#include "rekonq_defines.h" + +// Ui Includes +#include "ui_sync_check.h" + +// Qt Includes +#include <QWizardPage> + + +class SyncCheckWidget : public QWizardPage, private Ui::SyncCheck +{ + Q_OBJECT + +public: + SyncCheckWidget(QWidget *parent = 0); + void initializePage(); + +private Q_SLOTS: + void updateWidget(Rekonq::SyncData, bool, QString); +}; + +#endif // SYNC_CHECK_WIDGET_H diff --git a/src/sync/syncdatawidget.cpp b/src/sync/syncdatawidget.cpp new file mode 100644 index 00000000..635c6239 --- /dev/null +++ b/src/sync/syncdatawidget.cpp @@ -0,0 +1,86 @@ +/* ============================================================ +* +* This file is a part of the rekonq project +* +* Copyright (C) 2011-2012 by Andrea Diamantini <adjam7 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 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/>. +* +* ============================================================ */ + + +// Self Includes +#include "syncdatawidget.h" +#include "syncdatawidget.moc" + +// Auto Includes +#include "rekonq.h" + +// Local Includes +#include "syncmanager.h" +#include "syncassistant.h" + + +SyncDataWidget::SyncDataWidget(QWidget *parent) + : QWizardPage(parent) +{ + setupUi(this); +} + +void SyncDataWidget::initializePage() +{ + + kcfg_syncBookmarks->setDisabled(true); + kcfg_syncHistory->setDisabled(true); + kcfg_syncPasswords->setDisabled(true); + + switch (ReKonfig::syncType()) + { + //Ftp Sync Handler + case 0: + kcfg_syncBookmarks->setEnabled(true); + kcfg_syncHistory->setEnabled(true); + kcfg_syncPasswords->setEnabled(true); + break; + //Google Sync Handler + case 1: + //Opera Sync Handler + case 2: + kcfg_syncBookmarks->setEnabled(true); + break; + default: + kDebug() << "Unknown sync type!"; + } + + kcfg_syncBookmarks->setChecked(ReKonfig::syncBookmarks()); + kcfg_syncHistory->setChecked(ReKonfig::syncHistory()); + kcfg_syncPasswords->setChecked(ReKonfig::syncPasswords()); + +} + + +int SyncDataWidget::nextId() const +{ + // save + + ReKonfig::setSyncBookmarks(kcfg_syncBookmarks->isChecked()); + ReKonfig::setSyncHistory(kcfg_syncHistory->isChecked()); + ReKonfig::setSyncPasswords(kcfg_syncPasswords->isChecked()); + + return SyncAssistant::Page_Check; +} diff --git a/src/sync/syncdatawidget.h b/src/sync/syncdatawidget.h new file mode 100644 index 00000000..cfec1d49 --- /dev/null +++ b/src/sync/syncdatawidget.h @@ -0,0 +1,54 @@ +/* ============================================================ +* +* This file is a part of the rekonq project +* +* Copyright (C) 2011-2012 by Andrea Diamantini <adjam7 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 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 SYNC_DATA_WIDGET_H +#define SYNC_DATA_WIDGET_H + + +// Rekonq Includes +#include "rekonq_defines.h" + +// Ui Includes +#include "ui_sync_data.h" + +// Qt Includes +#include <QWizardPage> + + +class SyncDataWidget : public QWizardPage, private Ui::SyncData +{ + Q_OBJECT + +public: + SyncDataWidget(QWidget *parent = 0); + + int nextId() const; + + void initializePage(); + +}; + +#endif // SYNC_WIDGET_H diff --git a/src/sync/syncftpsettingswidget.cpp b/src/sync/syncftpsettingswidget.cpp new file mode 100644 index 00000000..5eb6bfdc --- /dev/null +++ b/src/sync/syncftpsettingswidget.cpp @@ -0,0 +1,63 @@ +/* ============================================================ +* +* This file is a part of the rekonq project +* +* Copyright (C) 2011 by Andrea Diamantini <adjam7 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 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/>. +* +* ============================================================ */ + + +// Self Includes +#include "syncftpsettingswidget.h" +#include "syncftpsettingswidget.moc" + +// Auto Includes +#include "rekonq.h" + +// Local Includes +#include "syncassistant.h" + + +SyncFTPSettingsWidget::SyncFTPSettingsWidget(QWidget *parent) + : QWizardPage(parent) +{ + setupUi(this); + + kcfg_syncHost->setText(ReKonfig::syncHost()); + kcfg_syncUser->setText(ReKonfig::syncUser()); + kcfg_syncPass->setText(ReKonfig::syncPass()); + kcfg_syncPath->setText(ReKonfig::syncPath()); + kcfg_syncPort->setValue(ReKonfig::syncPort()); + + kcfg_syncPass->setPasswordMode(true); +} + + +int SyncFTPSettingsWidget::nextId() const +{ + // save + ReKonfig::setSyncHost(kcfg_syncHost->text()); + ReKonfig::setSyncUser(kcfg_syncUser->text()); + ReKonfig::setSyncPass(kcfg_syncPass->text()); + ReKonfig::setSyncPath(kcfg_syncPath->text()); + ReKonfig::setSyncPort(kcfg_syncPort->value()); + + return SyncAssistant::Page_Data; +} diff --git a/src/sync/syncftpsettingswidget.h b/src/sync/syncftpsettingswidget.h new file mode 100644 index 00000000..d067eef4 --- /dev/null +++ b/src/sync/syncftpsettingswidget.h @@ -0,0 +1,51 @@ +/* ============================================================ +* +* This file is a part of the rekonq project +* +* Copyright (C) 2011 by Andrea Diamantini <adjam7 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 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 SYNC_FTP_SETTINGS_WIDGET_H +#define SYNC_FTP_SETTINGS_WIDGET_H + + +// Rekonq Includes +#include "rekonq_defines.h" + +// Ui Includes +#include "ui_sync_ftp_settings.h" + +// Qt Includes +#include <QWizardPage> + + +class SyncFTPSettingsWidget : public QWizardPage, private Ui::SyncFTPSettings +{ + Q_OBJECT + +public: + SyncFTPSettingsWidget(QWidget *parent = 0); + + int nextId() const; +}; + +#endif // SYNC_FTP_SETTINGS_WIDGET_H diff --git a/src/sync/syncgooglesettingswidget.cpp b/src/sync/syncgooglesettingswidget.cpp new file mode 100644 index 00000000..6c364b38 --- /dev/null +++ b/src/sync/syncgooglesettingswidget.cpp @@ -0,0 +1,61 @@ +/* ============================================================ +* +* This file is a part of the rekonq project +* +* Copyright (C) 2012 by Siteshwar Vashisht <siteshwar at gmail dot com> +* Copyright (C) 2011-2012 by Andrea Diamantini <adjam7 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 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/>. +* +* ============================================================ */ + + +// Self Includes +#include "syncgooglesettingswidget.h" +#include "syncgooglesettingswidget.moc" + +// Auto Includes +#include "rekonq.h" + +// Local Includes +#include "syncassistant.h" + + +SyncGoogleSettingsWidget::SyncGoogleSettingsWidget(QWidget *parent) + : QWizardPage(parent) +{ + setupUi(this); + kcfg_syncUser->setText(ReKonfig::syncUser()); + kcfg_syncPass->setText(ReKonfig::syncPass()); + + kcfg_syncPass->setPasswordMode(true); +} + + +int SyncGoogleSettingsWidget::nextId() const +{ + // save + ReKonfig::setSyncHost("http://bookmarks.google.com/"); + ReKonfig::setSyncUser(kcfg_syncUser->text()); + ReKonfig::setSyncPass(kcfg_syncPass->text()); + + ReKonfig::setSyncHistory(false); + ReKonfig::setSyncPasswords(false); + + return SyncAssistant::Page_Data; +} diff --git a/src/sync/syncgooglesettingswidget.h b/src/sync/syncgooglesettingswidget.h new file mode 100644 index 00000000..a51b1d2c --- /dev/null +++ b/src/sync/syncgooglesettingswidget.h @@ -0,0 +1,52 @@ +/* ============================================================ +* +* This file is a part of the rekonq project +* +* Copyright (C) 2011-2012 by Siteshwar Vashisht <siteshwar AT gmail.com> +* Copyright (C) 2011-20112 by Andrea Diamantini <adjam7 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 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 SYNC_GOOGLE_SETTINGS_WIDGET_H +#define SYNC_GOOGLE_SETTINGS_WIDGET_H + + +// Rekonq Includes +#include "rekonq_defines.h" + +// Ui Includes +#include "ui_sync_google_settings.h" + +// Qt Includes +#include <QWizardPage> + + +class SyncGoogleSettingsWidget : public QWizardPage, private Ui::SyncGoogleSettings +{ + Q_OBJECT + +public: + SyncGoogleSettingsWidget(QWidget *parent = 0); + + int nextId() const; +}; + +#endif // SYNC_GOOGLE_SETTINGS_WIDGET_H diff --git a/src/sync/synchandler.cpp b/src/sync/synchandler.cpp new file mode 100644 index 00000000..759af064 --- /dev/null +++ b/src/sync/synchandler.cpp @@ -0,0 +1,41 @@ +/* ============================================================ +* +* This file is a part of the rekonq project +* +* Copyright (C) 2011 by Andrea Diamantini <adjam7 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 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/>. +* +* ============================================================ */ + + +// Self Includes +#include "synchandler.h" +#include "synchandler.moc" + + +SyncHandler::SyncHandler(QObject *parent) + : QObject(parent) + , _firstTimeSynced(false) +{ +} + + +SyncHandler::~SyncHandler() +{ +} diff --git a/src/sync/synchandler.h b/src/sync/synchandler.h new file mode 100644 index 00000000..32266d7c --- /dev/null +++ b/src/sync/synchandler.h @@ -0,0 +1,61 @@ +/* ============================================================ +* +* This file is a part of the rekonq project +* +* Copyright (C) 2011 by Andrea Diamantini <adjam7 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 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 SYNC_HANDLER_H +#define SYNC_HANDLER_H + + +// Rekonq Includes +#include "rekonq_defines.h" + +// Qt Includes +#include <QObject> + + +class SyncHandler : public QObject +{ + Q_OBJECT + +public: + SyncHandler(QObject *parent = 0); + virtual ~SyncHandler(); + + virtual void syncHistory() = 0; + virtual void syncBookmarks() = 0; + virtual void syncPasswords() = 0; + + virtual void initialLoadAndCheck() = 0; + +Q_SIGNALS: + void syncStatus(Rekonq::SyncData type, bool syncDone, QString message); + +protected: + bool _firstTimeSynced; + + +}; + +#endif // SYNC_HANDLER_H diff --git a/src/sync/synchosttypewidget.cpp b/src/sync/synchosttypewidget.cpp new file mode 100644 index 00000000..289f5e5e --- /dev/null +++ b/src/sync/synchosttypewidget.cpp @@ -0,0 +1,107 @@ +/* ============================================================ +* +* This file is a part of the rekonq project +* +* Copyright (C) 2011-2012 by Andrea Diamantini <adjam7 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 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/>. +* +* ============================================================ */ + + +// Self Includes +#include "synchosttypewidget.h" +#include "synchosttypewidget.moc" + +// Auto Includes +#include "rekonq.h" + +// Local Includes +#include "syncassistant.h" + + +SyncHostTypeWidget::SyncHostTypeWidget(QWidget *parent) + : QWizardPage(parent) + , _changed(false) +{ + setupUi(this); + connect(kcfg_syncEnabled, SIGNAL(clicked()), this, SLOT(hasChanged())); + + kcfg_syncEnabled->setChecked(ReKonfig::syncEnabled()); + if (ReKonfig::syncType() == 0) + ftpRadioButton->setChecked(true); + else if (ReKonfig::syncType() == 1) + googleRadioButton->setChecked(true); + else if (ReKonfig::syncType() == 2) + operaRadioButton->setChecked(true); + else + nullRadioButton->setChecked(true); + + enablewidgets(ReKonfig::syncEnabled()); +} + + +bool SyncHostTypeWidget::changed() +{ + return _changed; +} + + +void SyncHostTypeWidget::hasChanged() +{ + enablewidgets(kcfg_syncEnabled->isChecked()); + + _changed = true; + emit changed(true); +} + +int SyncHostTypeWidget::nextId() const +{ + ReKonfig::setSyncEnabled(kcfg_syncEnabled->isChecked()); + + if (!ReKonfig::syncEnabled()) + return SyncAssistant::Page_Check; + + // save + if (ftpRadioButton->isChecked()) + { + ReKonfig::setSyncType(0); + return SyncAssistant::Page_FTP_Settings; + } + else if (googleRadioButton->isChecked()) + { + ReKonfig::setSyncType(1); + return SyncAssistant::Page_Google_Settings; + } + else if (operaRadioButton->isChecked()) + { + ReKonfig::setSyncType(2); + return SyncAssistant::Page_Opera_Settings; + } + else + { + ReKonfig::setSyncType(3); + return SyncAssistant::Page_Check; + } + +} + +void SyncHostTypeWidget::enablewidgets(bool b) +{ + hostGroupBox->setEnabled(b); +} diff --git a/src/sync/synchosttypewidget.h b/src/sync/synchosttypewidget.h new file mode 100644 index 00000000..4f577958 --- /dev/null +++ b/src/sync/synchosttypewidget.h @@ -0,0 +1,63 @@ +/* ============================================================ +* +* This file is a part of the rekonq project +* +* Copyright (C) 2011-2012 by Andrea Diamantini <adjam7 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 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 SYNC_HOST_TYPE_WIDGET_H +#define SYNC_HOST_TYPE_WIDGET_H + + +// Rekonq Includes +#include "rekonq_defines.h" + +// Ui Includes +#include "ui_sync_host_type.h" + +// Qt Includes +#include <QWizardPage> + + +class SyncHostTypeWidget : public QWizardPage, private Ui::SyncHostType +{ + Q_OBJECT + +public: + SyncHostTypeWidget(QWidget *parent = 0); + + int nextId() const; + bool changed(); + +Q_SIGNALS: + void changed(bool); + +private Q_SLOTS: + void hasChanged(); + +private: + void enablewidgets(bool b); + bool _changed; + +}; + +#endif // SYNC_HOST_TYPE_WIDGET_H diff --git a/src/sync/syncmanager.cpp b/src/sync/syncmanager.cpp new file mode 100644 index 00000000..e31c226d --- /dev/null +++ b/src/sync/syncmanager.cpp @@ -0,0 +1,186 @@ +/* ============================================================ +* +* This file is a part of the rekonq project +* +* Copyright (C) 2011-2012 by Andrea Diamantini <adjam7 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 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/>. +* +* ============================================================ */ + + +// Self Includes +#include "syncmanager.h" +#include "syncmanager.moc" + +// Auto Includes +#include "rekonq.h" + +// Config Includes +#include "config-qca2.h" +#include "config-qtoauth.h" + +// Local Includes +#include "application.h" +#include "bookmarkmanager.h" +#include "historymanager.h" + +#include "syncassistant.h" +#include "ftpsynchandler.h" +#include "googlesynchandler.h" + +#if (defined HAVE_QCA2 && defined HAVE_QTOAUTH) +#include "operasynchandler.h" +#endif + +// KDE Includes +#include <KLocalizedString> + +// Qt Includes +#include <QPointer> + + +QWeakPointer<SyncManager> SyncManager::s_syncManager; + + +SyncManager *SyncManager::self() +{ + if (s_syncManager.isNull()) + { + s_syncManager = new SyncManager(qApp); + } + return s_syncManager.data(); +} + + +// ---------------------------------------------------------------------------------------------- + + +SyncManager::SyncManager(QObject *parent) + : QObject(parent) +{ + loadSettings(); +} + + +SyncManager::~SyncManager() +{ + if (!_syncImplementation.isNull()) + { + delete _syncImplementation.data(); + _syncImplementation.clear(); + } +} + + +void SyncManager::loadSettings() +{ + if (ReKonfig::syncEnabled()) + { + // reset syncer + if (!_syncImplementation.isNull()) + { + delete _syncImplementation.data(); + _syncImplementation.clear(); + } + + switch (ReKonfig::syncType()) + { + case 0: + _syncImplementation = new FTPSyncHandler(this); + break; + case 1: + _syncImplementation = new GoogleSyncHandler(this); + break; +#if (defined HAVE_QCA2 && defined HAVE_QTOAUTH) + case 2: + _syncImplementation = new OperaSyncHandler(this); + break; +#endif + default: + kDebug() << "/dev/null"; + return; + } + + + // --- Connect syncmanager to bookmarks & history manager + + // bookmarks + ReKonfig::syncBookmarks() + ? connect(BookmarkManager::self(), SIGNAL(bookmarksUpdated()), this, SLOT(syncBookmarks())) + : disconnect(BookmarkManager::self(), SIGNAL(bookmarksUpdated()), this, SLOT(syncBookmarks())) + ; + + // history + ReKonfig::syncHistory() + ? connect(HistoryManager::self(), SIGNAL(historySaved()), this, SLOT(syncHistory())) + : disconnect(HistoryManager::self(), SIGNAL(historySaved()), this, SLOT(syncHistory())) + ; + + _syncImplementation.data()->initialLoadAndCheck(); + // NOTE: password sync will be called just on save + } + else + { + // bookmarks + disconnect(BookmarkManager::self(), SIGNAL(bookmarksUpdated()), this, SLOT(syncBookmarks())); + + // history + disconnect(HistoryManager::self(), SIGNAL(historySaved()), this, SLOT(syncHistory())); + } +} + + +void SyncManager::showSettings() +{ + QPointer<SyncAssistant> dialog = new SyncAssistant(); + dialog->exec(); + + dialog->deleteLater(); +} + + +// --------------------------------------------------------------------------------------- + + +void SyncManager::syncBookmarks() +{ + if (!_syncImplementation.isNull()) + { + _syncImplementation.data()->syncBookmarks(); + } +} + + +void SyncManager::syncHistory() +{ + if (!_syncImplementation.isNull()) + { + _syncImplementation.data()->syncHistory(); + } +} + + +void SyncManager::syncPasswords() +{ + if (!_syncImplementation.isNull()) + { + _syncImplementation.data()->syncPasswords(); + } +} + diff --git a/src/sync/syncmanager.h b/src/sync/syncmanager.h new file mode 100644 index 00000000..a144490e --- /dev/null +++ b/src/sync/syncmanager.h @@ -0,0 +1,78 @@ +/* ============================================================ +* +* This file is a part of the rekonq project +* +* Copyright (C) 2011-2012 by Andrea Diamantini <adjam7 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 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 SYNC_MANAGER_H +#define SYNC_MANAGER_H + + +// Rekonq Includes +#include "rekonq_defines.h" + +// Local Includes +#include "synchandler.h" + +// Qt Includes +#include <QObject> +#include <QWeakPointer> + + +class REKONQ_TESTS_EXPORT SyncManager : public QObject +{ + Q_OBJECT + +public: + /** + * Entry point. + * Access to SyncManager class by using + * SyncManager::self()->thePublicMethodYouNeed() + */ + static SyncManager *self(); + + ~SyncManager(); + + SyncHandler *handler() const + { + return _syncImplementation.data(); + }; + +private: + SyncManager(QObject *parent = 0); + +public Q_SLOTS: + void syncBookmarks(); + void syncHistory(); + void syncPasswords(); + + void loadSettings(); + void showSettings(); + +private: + QWeakPointer<SyncHandler> _syncImplementation; + + static QWeakPointer<SyncManager> s_syncManager; +}; + +#endif // SYNC_MANAGER_H diff --git a/src/sync/syncoperasettingswidget.cpp b/src/sync/syncoperasettingswidget.cpp new file mode 100644 index 00000000..a45ae70c --- /dev/null +++ b/src/sync/syncoperasettingswidget.cpp @@ -0,0 +1,85 @@ +/* ============================================================ +* +* This file is a part of the rekonq project +* +* Copyright (C) 2012 by Siteshwar Vashisht <siteshwar at gmail dot com> +* Copyright (C) 2011-2012 by Andrea Diamantini <adjam7 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 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/>. +* +* ============================================================ */ + + +// Self Includes +#include "syncoperasettingswidget.h" +#include "syncoperasettingswidget.moc" + +// Auto Includes +#include "rekonq.h" + +// Config Includes +#include "config-qca2.h" +#include "config-qtoauth.h" + +// Local Includes +#include "syncassistant.h" + + +SyncOperaSettingsWidget::SyncOperaSettingsWidget(QWidget *parent) + : QWizardPage(parent) +{ + setupUi(this); + +#if (defined HAVE_QCA2 && defined HAVE_QTOAUTH) + + kcfg_syncUser->setText(ReKonfig::syncUser()); + kcfg_syncPass->setText(ReKonfig::syncPass()); + + kcfg_syncPass->setPasswordMode(true); + +#else + + kcfg_syncUser->setEnabled(false); + kcfg_syncPass->setEnabled(false); + + infoLabel->setText(i18n("Rekonq has been compiled without support for Opera Sync")); + +#endif +} + + +int SyncOperaSettingsWidget::nextId() const +{ +#if (defined HAVE_QCA2 && defined HAVE_QTOAUTH) + + // save + ReKonfig::setSyncHost("http://link.opera.com/"); + ReKonfig::setSyncUser(kcfg_syncUser->text()); + ReKonfig::setSyncPass(kcfg_syncPass->text()); + + ReKonfig::setSyncHistory(false); + ReKonfig::setSyncPasswords(false); + + return SyncAssistant::Page_Data; + +#else + + return SyncAssistant::Page_Check; + +#endif +} diff --git a/src/sync/syncoperasettingswidget.h b/src/sync/syncoperasettingswidget.h new file mode 100644 index 00000000..53e95699 --- /dev/null +++ b/src/sync/syncoperasettingswidget.h @@ -0,0 +1,52 @@ +/* ============================================================ +* +* This file is a part of the rekonq project +* +* Copyright (C) 2011-2012 by Siteshwar Vashisht <siteshwar AT gmail.com> +* Copyright (C) 2011-2012 by Andrea Diamantini <adjam7 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 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 SYNC_OPERA_SETTINGS_WIDGET_H +#define SYNC_OPERA_SETTINGS_WIDGET_H + + +// Rekonq Includes +#include "rekonq_defines.h" + +// Ui Includes +#include "ui_sync_opera_settings.h" + +// Qt Includes +#include <QWizardPage> + + +class SyncOperaSettingsWidget : public QWizardPage, private Ui::SyncOperaSettings +{ + Q_OBJECT + +public: + SyncOperaSettingsWidget(QWidget *parent = 0); + + int nextId() const; +}; + +#endif // SYNC_OPERA_SETTINGS_WIDGET_H |