From d6f2628630bf2f3add48679c947bf464ee38dc81 Mon Sep 17 00:00:00 2001 From: Andrea Diamantini Date: Tue, 31 Jul 2012 23:13:30 +0200 Subject: Restore sync manager --- src/sync/operasynchandler.cpp | 916 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 916 insertions(+) create mode 100644 src/sync/operasynchandler.cpp (limited to 'src/sync/operasynchandler.cpp') 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 +* Copyright (C) 2011 by Andrea Diamantini +* +* +* 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 . +* +* ============================================================ */ + + +// Self Includes +#include "operasynchandler.h" +#include "operasynchandler.moc" + +// Auto Includes +#include "rekonq.h" + +// Local Includes +#include "bookmarkmanager.h" + +// KDE Includes +#include +#include +#include + + +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +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 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; + } +} -- cgit v1.2.1