sync-monitor-0.2+16.04.20160304/ 0000755 0000156 0000165 00000000000 12666332257 016370 5 ustar pbuser pbgroup 0000000 0000000 sync-monitor-0.2+16.04.20160304/tests/ 0000755 0000156 0000165 00000000000 12666332257 017532 5 ustar pbuser pbgroup 0000000 0000000 sync-monitor-0.2+16.04.20160304/tests/unittest/ 0000755 0000156 0000165 00000000000 12666332257 021411 5 ustar pbuser pbgroup 0000000 0000000 sync-monitor-0.2+16.04.20160304/tests/unittest/sync-queue-test.cpp 0000644 0000156 0000165 00000013754 12666332064 025176 0 ustar pbuser pbgroup 0000000 0000000 /*
* Copyright 2014 Canonical Ltd.
*
* This file is part of sync-monitor.
*
* sync-monitor 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; version 3.
*
* contact-service-app 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 .
*/
#include "sync-account-mock.h"
#include "src/sync-queue.h"
#include
#include
#include
#include
class SyncQueueTest : public QObject
{
Q_OBJECT
private Q_SLOTS:
void testRegisterNewAccount()
{
QStringList expectedServices;
SyncQueue queue;
SyncAccountMock account;
expectedServices << "contacts" << "calendar";
// empty queue
QCOMPARE(queue.isEmpty(), true);
QCOMPARE(queue.count(), 0);
EXPECT_CALL(account, availableServices())
.Times(1)
.WillOnce(::testing::Return(expectedServices));
// push a account
queue.push(&account);
QCOMPARE(queue.isEmpty(), false);
QCOMPARE(queue.count(), 2);
Q_FOREACH(const QString &serviceName, expectedServices) {
QVERIFY(queue.contains(&account, serviceName));
}
}
void testRegiterTwoAccounts()
{
QStringList expectedServices;
SyncQueue queue;
SyncAccountMock account;
SyncAccountMock account2;
expectedServices << "contacts" << "calendar";
EXPECT_CALL(account, availableServices())
.WillRepeatedly(::testing::Return(expectedServices));
EXPECT_CALL(account2, availableServices())
.WillRepeatedly(::testing::Return(expectedServices));
queue.push(&account);
queue.push(&account2);
// Check if the account was registered correct
QCOMPARE(queue.isEmpty(), false);
QCOMPARE(queue.count(), 4);
Q_FOREACH(const QString &serviceName, expectedServices) {
QVERIFY(queue.contains(&account, serviceName));
QVERIFY(queue.contains(&account2, serviceName));
}
}
void testRemoveAccount()
{
QStringList expectedServices;
SyncQueue queue;
SyncAccountMock account;
SyncAccountMock account2;
expectedServices << "contacts" << "calendar";
EXPECT_CALL(account, availableServices())
.WillRepeatedly(::testing::Return(expectedServices));
EXPECT_CALL(account2, availableServices())
.WillRepeatedly(::testing::Return(expectedServices));
queue.push(&account);
queue.push(&account2);
// remove all services from account
queue.remove(&account);
// Check if the account was registered correct
QCOMPARE(queue.isEmpty(), false);
QCOMPARE(queue.count(), 2);
Q_FOREACH(const QString &serviceName, expectedServices) {
QVERIFY(queue.contains(&account2, serviceName));
QVERIFY(!queue.contains(&account, serviceName));
}
// remove calendar services from account2
queue.remove(&account2, "calendar");
// Check if the account was registered correct
QCOMPARE(queue.isEmpty(), false);
QCOMPARE(queue.count(), 1);
QVERIFY(queue.contains(&account2, "contacts"));
QVERIFY(!queue.contains(&account2, "calendar"));
}
void testPushAccountTwice()
{
QStringList expectedServices;
SyncQueue queue;
SyncAccountMock account;
expectedServices << "contacts" << "calendar";
EXPECT_CALL(account, availableServices())
.Times(2)
.WillRepeatedly(::testing::Return(expectedServices));
// push a account twice
queue.push(&account);
queue.push(&account);
// Check if the account was registered only once
QCOMPARE(queue.isEmpty(), false);
QCOMPARE(queue.count(), 2);
Q_FOREACH(const QString &serviceName, expectedServices) {
QVERIFY(queue.contains(&account, serviceName));
}
}
void testPopAccount()
{
QStringList expectedServices;
SyncQueue queue;
SyncAccountMock account;
SyncAccountMock account2;
expectedServices << "contacts" << "calendar";
EXPECT_CALL(account, availableServices())
.WillRepeatedly(::testing::Return(expectedServices));
EXPECT_CALL(account2, availableServices())
.WillRepeatedly(::testing::Return(expectedServices));
queue.push(&account);
queue.push(&account2,"", false);
// account with contacts
SyncJob job = queue.popNext();
QCOMPARE(job.serviceName(), expectedServices.first());
QVERIFY(job.account() == &account);
// account with calendar
job = queue.popNext();
QCOMPARE(job.serviceName(), expectedServices[1]);
QVERIFY(job.account() == &account);
// account2 with contacts
job = queue.popNext();
QCOMPARE(job.serviceName(), expectedServices.first());
QVERIFY(job.account() == &account2);
// acount2 with calendar
job = queue.popNext();
QCOMPARE(job.serviceName(), expectedServices[1]);
QVERIFY(job.account() == &account2);
}
};
int main(int argc, char *argv[])
{
// The following line causes Google Mock to throw an exception on failure,
// which will be interpreted by your testing framework as a test failure.
::testing::GTEST_FLAG(throw_on_failure) = true;
::testing::InitGoogleMock(&argc, argv);
QCoreApplication app(argc, argv);
app.setAttribute(Qt::AA_Use96Dpi, true);
SyncQueueTest tc;
return QTest::qExec(&tc, argc, argv);
}
#include "sync-queue-test.moc"
sync-monitor-0.2+16.04.20160304/tests/unittest/sync-account-mock.h 0000644 0000156 0000165 00000001754 12666332064 025122 0 ustar pbuser pbgroup 0000000 0000000 /*
* Copyright 2014 Canonical Ltd.
*
* This file is part of sync-monitor.
*
* sync-monitor 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; version 3.
*
* contact-service-app 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 .
*/
#ifndef __SYNC_ACCOUNT_MOCK__
#define __SYNC_ACCOUNT_MOCK__
#include
#include
#include "src/sync-account.h"
class SyncAccountMock : public SyncAccount
{
Q_OBJECT
public:
SyncAccountMock() : SyncAccount(0, 0) {}
MOCK_CONST_METHOD0(availableServices, QStringList());
};
#endif
sync-monitor-0.2+16.04.20160304/tests/unittest/eds-helper-mock.h 0000644 0000156 0000165 00000003136 12666332064 024540 0 ustar pbuser pbgroup 0000000 0000000 /*
* Copyright 2014 Canonical Ltd.
*
* This file is part of sync-monitor.
*
* sync-monitor 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; version 3.
*
* contact-service-app 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 .
*/
#ifndef __EDS_HELPER_MOCK__
#define __EDS_HELPER_MOCK__
#include
#include
#include
#include
#include
#include
#include "src/eds-helper.h"
class EdsHelperMock : public EdsHelper
{
Q_OBJECT
public:
EdsHelperMock(QObject *parent = 0)
: EdsHelper(parent, "memory", "memory")
{
setEnabled(true);
}
QtOrganizer::QOrganizerManager *organizerEngine()
{ return m_organizerEngine; }
QtContacts::QContactManager *contactEngine()
{ return m_contactEngine; }
void trackCollectionFromItem(QtOrganizer::QOrganizerItem *item)
{ m_trackedItem = item; }
virtual QString getCollectionIdFromItemId(const QtOrganizer::QOrganizerItemId&) const
{ return m_trackedItem->collectionId().toString(); }
private:
QtOrganizer::QOrganizerItem *m_trackedItem;
};
#endif
sync-monitor-0.2+16.04.20160304/tests/unittest/eds-helper-test.cpp 0000644 0000156 0000165 00000010444 12666332064 025121 0 ustar pbuser pbgroup 0000000 0000000 /*
* Copyright 2014 Canonical Ltd.
*
* This file is part of sync-monitor.
*
* sync-monitor 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; version 3.
*
* contact-service-app 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 .
*/
#include "eds-helper-mock.h"
#include "config.h"
#include
#include
#include
#include
#include
#include
#include
#include
using namespace QtContacts;
using namespace QtOrganizer;
class EdsHelperTest : public QObject
{
Q_OBJECT
private Q_SLOTS:
void testCreateAContact()
{
EdsHelperMock mock;
QSignalSpy spy(&mock, SIGNAL(dataChanged(QString,QString)));
QContact c;
QContactName name;
name.setFirstName("Foo");
name.setLastName("Bar");
c.saveDetail(&name);
QContactSyncTarget syncTarget;
syncTarget.setSyncTarget("address-book-test");
c.saveDetail(&syncTarget);
mock.contactEngine()->saveContact(&c);
// check if the signal dataChanged was fired with contacts
QTRY_COMPARE(spy.count() , 1);
QList args = spy.takeFirst();
QCOMPARE(args[0].toString(), QStringLiteral(CONTACTS_SERVICE_NAME));
QCOMPARE(args[1].toString(), QStringLiteral("address-book-test"));
}
void testCreateACalendarEvent()
{
EdsHelperMock mock;
QSignalSpy spy(&mock, SIGNAL(dataChanged(QString,QString)));
QOrganizerEvent ev;
ev.setDescription("test");
ev.setDisplayLabel("display test");
ev.setStartDateTime(QDateTime::currentDateTime());
mock.trackCollectionFromItem(&ev);
mock.organizerEngine()->saveItem(&ev);
// check if the signal dataChanged was fired with contacts
QTRY_COMPARE(spy.count(), 1);
QList args = spy.takeFirst();
QCOMPARE(args[0].toString(), QStringLiteral(CALENDAR_SERVICE_NAME));
QCOMPARE(args[1].toString(), QStringLiteral("Default Collection"));
}
void testFreezeNotify()
{
EdsHelperMock mock;
mock.freezeNotify();
QSignalSpy spy(&mock, SIGNAL(dataChanged(QString,QString)));
// create contact
QContact c;
QContactName name;
name.setFirstName("Foo");
name.setLastName("Bar");
c.saveDetail(&name);
QContactSyncTarget syncTarget;
syncTarget.setSyncTarget("address-book-test");
c.saveDetail(&syncTarget);
mock.contactEngine()->saveContact(&c);
QCOMPARE(spy.count(), 0);
// create a event
QOrganizerEvent ev;
ev.setDescription("test");
ev.setDisplayLabel("display test");
ev.setStartDateTime(QDateTime::currentDateTime());
mock.trackCollectionFromItem(&ev);
mock.organizerEngine()->saveItem(&ev);
QCOMPARE(spy.count(), 0);
// flush all pending events
mock.flush();
QTRY_COMPARE(spy.count(), 2);
QList args = spy.takeFirst();
QCOMPARE(args[0].toString(), QStringLiteral(CONTACTS_SERVICE_NAME));
QCOMPARE(args[1].toString(), QStringLiteral("address-book-test"));
args = spy.takeFirst();
QCOMPARE(args[0].toString(), QStringLiteral(CALENDAR_SERVICE_NAME));
QCOMPARE(args[1].toString(), QStringLiteral("Default Collection"));
}
};
int main(int argc, char *argv[])
{
// The following line causes Google Mock to throw an exception on failure,
// which will be interpreted by your testing framework as a test failure.
::testing::GTEST_FLAG(throw_on_failure) = true;
::testing::InitGoogleMock(&argc, argv);
QCoreApplication app(argc, argv);
app.setAttribute(Qt::AA_Use96Dpi, true);
EdsHelperTest tc;
return QTest::qExec(&tc, argc, argv);
}
#include "eds-helper-test.moc"
sync-monitor-0.2+16.04.20160304/tests/unittest/CMakeLists.txt 0000644 0000156 0000165 00000001317 12666332064 024147 0 ustar pbuser pbgroup 0000000 0000000 macro(declare_test TESTNAME)
add_executable(${TESTNAME}
${ARGN})
qt5_use_modules(${TESTNAME} Core Test Contacts)
target_link_libraries(${TESTNAME}
${ACCOUNTS_LIBRARIES}
synq-lib
gmock
)
add_test(${TESTNAME} ${TESTNAME})
endmacro()
include_directories(
${CMAKE_SOURCE_DIR}
${CMAKE_BINARY_DIR}
${ACCOUNTS_INCLUDE_DIRS}
${syncevolution-qt_SOURCE_DIR}
${gmock_SOURCE_DIR}/gtest/include/
)
declare_test(sync-queue-test
sync-queue-test.cpp
sync-account-mock.h
)
declare_test(eds-helper-test
eds-helper-test.cpp
eds-helper-mock.h
)
sync-monitor-0.2+16.04.20160304/tests/CMakeLists.txt 0000644 0000156 0000165 00000000033 12666332064 022262 0 ustar pbuser pbgroup 0000000 0000000 add_subdirectory(unittest)
sync-monitor-0.2+16.04.20160304/src/ 0000755 0000156 0000165 00000000000 12666332257 017157 5 ustar pbuser pbgroup 0000000 0000000 sync-monitor-0.2+16.04.20160304/src/provider-template.h 0000644 0000156 0000165 00000002202 12666332064 022763 0 ustar pbuser pbgroup 0000000 0000000 /*
* Copyright 2014 Canonical Ltd.
*
* This file is part of sync-monitor.
*
* sync-monitor 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; version 3.
*
* contact-service-app 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 .
*/
#ifndef __PROVIDER_TEMPLATE_H__
#define __PROVIDER_TEMPLATE_H__
#include
#include
class ProviderTemplate
{
public:
ProviderTemplate();
~ProviderTemplate();
void load();
bool contains(const QString &provider) const;
QStringList supportedServices(const QString &provider) const;
QSettings *settings(const QString &provider) const;
private:
QMap m_providers;
QString m_baseDir;
};
#endif
sync-monitor-0.2+16.04.20160304/src/sync-dbus.cpp 0000644 0000156 0000165 00000007056 12666332064 021576 0 ustar pbuser pbgroup 0000000 0000000 /*
* Copyright 2014 Canonical Ltd.
*
* This file is part of sync-monitor.
*
* sync-monitor 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; version 3.
*
* contact-service-app 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 .
*/
#include "sync-dbus.h"
#include "sync-daemon.h"
#include "sync-account.h"
SyncDBus::SyncDBus(const QDBusConnection &connection, SyncDaemon *parent)
: QDBusAbstractAdaptor(parent),
m_parent(parent),
m_connection(connection),
m_clientCount(0)
{
connect(m_parent, SIGNAL(syncStarted(SyncAccount*,QString)), SLOT(onSyncStarted(SyncAccount*,QString)));
connect(m_parent, SIGNAL(syncFinished(SyncAccount*,QString)), SLOT(onSyncFinished(SyncAccount*,QString)));
connect(m_parent, SIGNAL(syncError(SyncAccount*,QString,QString)), SLOT(onSyncError(SyncAccount*,QString,QString)));
connect(m_parent, SIGNAL(syncAboutToStart()), SLOT(updateState()));
connect(m_parent, SIGNAL(done()), SLOT(updateState()));
connect(m_parent, SIGNAL(accountsChanged()), SIGNAL(enabledServicesChanged()));
connect(m_parent, SIGNAL(isOnlineChanged(bool)), SIGNAL(enabledServicesChanged()));
updateState();
}
void SyncDBus::sync(QStringList services)
{
if (services.isEmpty()) {
m_parent->syncAll(QString(), true);
} else {
Q_FOREACH(const QString &service, services) {
m_parent->syncAll(service, true);
}
}
}
void SyncDBus::syncAccount(quint32 accountId, const QString &service)
{
m_parent->syncAccount(accountId, service);
}
void SyncDBus::cancel(QStringList services)
{
if (services.isEmpty()) {
m_parent->cancel();
} else {
Q_FOREACH(const QString &service, services) {
m_parent->cancel(service);
}
}
}
QString SyncDBus::state() const
{
return m_state;
}
QStringList SyncDBus::enabledServices() const
{
// return enabled sercives only in online mode
if (m_parent->isOnline()) {
return m_parent->enabledServices();
} else {
return QStringList();
}
}
QStringList SyncDBus::servicesAvailable()
{
return m_parent->availableServices();
}
void SyncDBus::attach()
{
m_clientCount++;
Q_EMIT clientAttached(m_clientCount);
}
void SyncDBus::detach()
{
m_clientCount--;
Q_EMIT clientDeattached(m_clientCount);
}
void SyncDBus::onSyncStarted(SyncAccount *syncAcc, const QString &serviceName)
{
updateState();
Q_EMIT syncStarted(syncAcc->displayName(), serviceName);
}
void SyncDBus::onSyncFinished(SyncAccount *syncAcc, const QString &serviceName)
{
Q_EMIT syncFinished(syncAcc->displayName(), serviceName);
}
void SyncDBus::onSyncError(SyncAccount *syncAcc, const QString &serviceName, const QString &error)
{
qDebug() << "Sync error" << syncAcc->displayName() << serviceName << error;
Q_EMIT syncError(syncAcc->displayName(), serviceName, error);
}
void SyncDBus::updateState()
{
QString newState = "idle";
if (m_parent->isSyncing()) {
newState = "syncing";
} else if (m_parent->isPending()) {
newState = "pending";
}
if (newState != m_state) {
m_state = newState;
Q_EMIT stateChanged();
}
}
sync-monitor-0.2+16.04.20160304/src/sync-daemon.cpp 0000644 0000156 0000165 00000050312 12666332064 022075 0 ustar pbuser pbgroup 0000000 0000000 /*
* Copyright 2014 Canonical Ltd.
*
* This file is part of sync-monitor.
*
* sync-monitor 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; version 3.
*
* contact-service-app 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 .
*/
#include "config.h"
#include "sync-daemon.h"
#include "sync-account.h"
#include "sync-queue.h"
#include "sync-dbus.h"
#include "sync-i18n.h"
#include "eds-helper.h"
#include "notify-message.h"
#include "provider-template.h"
#include "sync-network.h"
#include
#include
#include
using namespace Accounts;
#define DAEMON_SYNC_TIMEOUT 1000 * 60 // one minute
#define SYNC_MONITOR_ICON_PATH "/usr/share/icons/ubuntu-mobile/actions/scalable/reload.svg"
SyncDaemon::SyncDaemon()
: QObject(0),
m_manager(0),
m_eds(0),
m_dbusAddaptor(0),
m_currentAccount(0),
m_syncing(false),
m_aboutToQuit(false),
m_firstClient(true)
{
m_provider = new ProviderTemplate();
m_provider->load();
m_syncQueue = new SyncQueue();
m_offlineQueue = new SyncQueue();
m_networkStatus = new SyncNetwork(this);
connect(m_networkStatus, SIGNAL(stateChanged(SyncNetwork::NetworkState)), SLOT(onOnlineStatusChanged(SyncNetwork::NetworkState)));
m_timeout = new QTimer(this);
m_timeout->setInterval(DAEMON_SYNC_TIMEOUT);
m_timeout->setSingleShot(true);
connect(m_timeout, SIGNAL(timeout()), SLOT(continueSync()));
}
SyncDaemon::~SyncDaemon()
{
quit();
delete m_timeout;
delete m_syncQueue;
delete m_offlineQueue;
delete m_networkStatus;
}
void SyncDaemon::setupAccounts()
{
if (m_manager) {
return;
}
qDebug() << "Loading accounts...";
m_manager = new Manager(this);
Q_FOREACH(const AccountId &accountId, m_manager->accountList()) {
addAccount(accountId, false);
}
connect(m_manager,
SIGNAL(accountCreated(Accounts::AccountId)),
SLOT(addAccount(Accounts::AccountId)));
connect(m_manager,
SIGNAL(accountRemoved(Accounts::AccountId)),
SLOT(removeAccount(Accounts::AccountId)));
Q_EMIT accountsChanged();
}
void SyncDaemon::setupTriggers()
{
m_eds = new EdsHelper(this, "");
connect(m_eds, &EdsHelper::dataChanged,
this, &SyncDaemon::onDataChanged);
}
void SyncDaemon::onDataChanged(const QString &serviceName, const QString &sourceName)
{
if (sourceName.isEmpty()) {
syncAll(serviceName);
} else {
Q_FOREACH(SyncAccount *acc, m_accounts.values()) {
if (acc->displayName() == sourceName) {
sync(acc, serviceName);
return;
}
}
}
}
void SyncDaemon::onClientAttached()
{
if (m_firstClient) {
m_firstClient = false;
// accept eds changes
qDebug() << "First client connected, will auto-sync on next EDS change";
m_eds->setEnabled(true);
}
}
void SyncDaemon::onOnlineStatusChanged(SyncNetwork::NetworkState state)
{
Q_EMIT isOnlineChanged(state != SyncNetwork::NetworkOffline);
if (state == SyncNetwork::NetworkOnline) {
qDebug() << "Device is online sync pending changes" << m_offlineQueue->count();
m_syncQueue->push(*m_offlineQueue);
m_offlineQueue->clear();
if (!m_syncing && !m_syncQueue->isEmpty()) {
qDebug() << "Will sync in" << DAEMON_SYNC_TIMEOUT / 1000 << "secs;";
m_syncing = true;
m_timeout->start();
} else {
qDebug() << "No change to sync";
}
} else if (state == SyncNetwork::NetworkOffline) {
qDebug() << "Device is offline cancel active syncs. There is a sync in progress?" << (m_currentAccount ? "Yes" : "No");
if (m_currentAccount) {
if (m_currentAccount->retrySync()) {
qDebug() << "Push sync to later sync";
m_offlineQueue->push(m_currentAccount, m_currentServiceName, false);
} else {
qDebug() << "Do not try re-sync the account";
}
m_currentAccount->cancel(m_currentServiceName);
}
if (m_timeout->isActive()) {
m_timeout->stop();
}
continueSync();
}
// make accounts available or not based on online status
Q_EMIT accountsChanged();
}
void SyncDaemon::syncAll(const QString &serviceName, bool runNow)
{
// if runNow is set we will sync all accounts
Q_FOREACH(SyncAccount *acc, m_accounts.values()) {
if (serviceName.isEmpty()) {
sync(acc, QString(), runNow);
} else if (acc->availableServices().contains(serviceName)) {
sync(acc, serviceName, runNow);
}
}
}
/*
* This is a helper function used on contact migration it only works for contacts sync
*/
void SyncDaemon::syncAccount(quint32 accountId, const QString &service)
{
Account *account = m_manager->account(accountId);
if (account) {
// fake a settings object
QSettings *contactSettings = new QSettings;
contactSettings->setValue("contacts/template", "WebDAV");
contactSettings->setValue("contacts/syncURL", "https://www.googleapis.com/.well-known/carddav");
contactSettings->setValue("contacts/uoa-service", "google-carddav");
contactSettings->setValue("contacts/sync-backend", "evolution-contacts");
contactSettings->setValue("contacts/sync-uri", "addressbook");
SyncAccount *acc = new SyncAccount(account, service, contactSettings, this);
if (!isOnline()) {
qWarning() << "Network is off ignore sync request";
Q_EMIT syncError(acc, service, "20017");
account->deleteLater();
} else {
acc->setRetrySync(false);
connect(acc, SIGNAL(syncStarted(QString, bool)),
SLOT(onAccountSyncStarted(QString, bool)));
connect(acc, SIGNAL(syncFinished(QString, bool, QString, QString)),
SLOT(onAccountSyncFinished(QString, bool, QString, QString)));
connect(acc, SIGNAL(syncError(QString,QString)),
SLOT(onAccountSyncError(QString,QString)));
connect(acc, SIGNAL(syncError(QString,QString)),
acc, SLOT(deleteLater()), Qt::QueuedConnection);
connect(acc, SIGNAL(syncFinished(QString,bool,QString,QString)),
acc, SLOT(deleteLater()), Qt::QueuedConnection);
contactSettings->setParent(acc);
sync(acc, service, true);
}
}
}
void SyncDaemon::cancel(const QString &serviceName)
{
Q_FOREACH(SyncAccount *acc, m_accounts.values()) {
if (serviceName.isEmpty()) {
cancel(acc);
} else if (acc->availableServices().contains(serviceName)) {
cancel(acc, serviceName);
}
}
}
void SyncDaemon::continueSync()
{
SyncJob job = m_syncQueue->popNext();
SyncNetwork::NetworkState netState = m_networkStatus->state();
bool continueSync = (netState == SyncNetwork::NetworkOnline) ||
(netState != SyncNetwork::NetworkOffline && job.runOnPayedConnection());
if (!continueSync) {
qDebug() << "Device is offline we will skip the sync.";
Q_FOREACH(const SyncJob &j, m_syncQueue->jobs()) {
if (j.account() && j.account()->retrySync()) {
qDebug() << "Push account to later sync3";
m_offlineQueue->push(j);
}
}
m_syncQueue->clear();
syncFinishedImpl();
return;
}
m_syncing = true;
// flush any change in EDS
m_eds->flush();
// freeze notifications during the sync, to save some CPU
m_eds->freezeNotify();
// sync the next service on the queue
if (!m_aboutToQuit && job.isValid()) {
m_currentServiceName = job.serviceName();
m_currentAccount = job.account();
} else {
m_currentAccount = 0;
}
if (m_currentAccount) {
// remove sync reqeust from offline queue
m_offlineQueue->remove(m_currentAccount, m_currentServiceName);
m_currentAccount->sync(m_currentServiceName);
} else {
syncFinishedImpl();
// The sync has done, unblock notifications
m_eds->unfreezeNotify();
}
}
bool SyncDaemon::registerService()
{
if (!m_dbusAddaptor) {
QDBusConnection connection = QDBusConnection::sessionBus();
if (connection.interface()->isServiceRegistered(SYNCMONITOR_SERVICE_NAME)) {
qWarning() << "SyncMonitor service already registered";
return false;
} else if (!connection.registerService(SYNCMONITOR_SERVICE_NAME)) {
qWarning() << "Could not register service!" << SYNCMONITOR_SERVICE_NAME;
return false;
}
m_dbusAddaptor = new SyncDBus(connection, this);
if (!connection.registerObject(SYNCMONITOR_OBJECT_PATH, this)) {
qWarning() << "Could not register object!" << SYNCMONITOR_OBJECT_PATH;
delete m_dbusAddaptor;
m_dbusAddaptor = 0;
return false;
}
connect(m_dbusAddaptor, SIGNAL(clientAttached(int)), SLOT(onClientAttached()));
}
return true;
}
void SyncDaemon::syncFinishedImpl()
{
m_timeout->stop();
m_currentAccount = 0;
m_currentServiceName.clear();
m_syncing = false;
Q_EMIT done();
qDebug() << "All syncs finished";
}
void SyncDaemon::run()
{
setupAccounts();
setupTriggers();
// export dbus interface
registerService();
}
bool SyncDaemon::isPending() const
{
// there is a sync request on the buffer
return (m_syncQueue && (m_syncQueue->count() > 0));
}
bool SyncDaemon::isSyncing() const
{
// the sync is happening right now
return (m_syncing && (m_currentAccount != 0));
}
QStringList SyncDaemon::availableServices() const
{
// TODO: check for all providers
return m_provider->supportedServices("google");
}
QStringList SyncDaemon::enabledServices() const
{
QSet services;
QStringList available = availableServices();
Q_FOREACH(SyncAccount *syncAcc, m_accounts) {
Q_FOREACH(const QString &service, syncAcc->enabledServices()) {
if (available.contains(service)) {
services << service;
}
}
}
return services.toList();
}
bool SyncDaemon::isOnline() const
{
return m_networkStatus->state() != SyncNetwork::NetworkOffline;
}
void SyncDaemon::addAccount(const AccountId &accountId, bool startSync)
{
Account *acc = m_manager->account(accountId);
if (!acc) {
qWarning() << "Fail to retrieve accounts:" << m_manager->lastError().message();
} else if (m_provider->contains(acc->providerName())) {
qDebug() << "Found account:" << acc->displayName();
SyncAccount *syncAcc = new SyncAccount(acc,
m_provider->settings(acc->providerName()),
this);
m_accounts.insert(accountId, syncAcc);
connect(syncAcc, SIGNAL(syncStarted(QString, bool)),
SLOT(onAccountSyncStarted(QString, bool)));
connect(syncAcc, SIGNAL(syncFinished(QString, bool, QString, QString)),
SLOT(onAccountSyncFinished(QString, bool, QString, QString)));
connect(syncAcc, SIGNAL(enableChanged(QString, bool)),
SLOT(onAccountEnableChanged(QString, bool)));
connect(syncAcc, SIGNAL(configured(QString)),
SLOT(onAccountConfigured(QString)), Qt::DirectConnection);
connect(syncAcc, SIGNAL(syncError(QString,QString)),
SLOT(onAccountSyncError(QString, QString)));
if (startSync) {
sync(syncAcc, QString(), true);
}
Q_EMIT accountsChanged();
}
}
void SyncDaemon::sync(bool runNow)
{
m_syncing = true;
if (runNow) {
m_timeout->stop();
continueSync();
} else {
// wait some time for new sync requests
m_timeout->start();
}
}
void SyncDaemon::sync(SyncAccount *syncAcc, const QString &serviceName, bool runNow)
{
qDebug() << "syn requested for account:" << syncAcc->displayName() << serviceName;
// check if the service is already in the sync queue or is the current operation
if (m_syncQueue->contains(syncAcc, serviceName) ||
((m_currentAccount == syncAcc) && (serviceName.isEmpty() || (serviceName == m_currentServiceName))) ) {
qDebug() << "Account aready in the queue, ignore request;";
} else {
qDebug() << "Pushed into queue with immediately sync?" << runNow << "Sync is running" << m_syncing;
m_syncQueue->push(syncAcc, serviceName, runNow);
// if not syncing start a full sync
if (!m_syncing) {
qDebug() << "Request sync";
sync(runNow);
Q_EMIT syncAboutToStart();
return;
}
}
// immediately request, force sync to start
if (runNow && !isSyncing()) {
sync(runNow);
Q_EMIT syncAboutToStart();
}
}
void SyncDaemon::cancel(SyncAccount *syncAcc, const QString &serviceName)
{
m_syncQueue->remove(syncAcc, serviceName);
syncAcc->cancel();
if (m_currentAccount == syncAcc) {
qDebug() << "Current sync canceled";
m_currentAccount = 0;
} else if (m_syncQueue->isEmpty()) {
syncFinishedImpl();
}
Q_EMIT syncError(syncAcc, serviceName, "canceled");
}
void SyncDaemon::removeAccount(const AccountId &accountId)
{
SyncAccount *syncAcc = m_accounts.take(accountId);
if (syncAcc) {
cancel(syncAcc);
m_eds->removeSource("", syncAcc->displayName());
}
Q_EMIT accountsChanged();
}
void SyncDaemon::destroyAccount()
{
QObject *sender = QObject::sender();
QObject *acc = sender->property("ACCOUNT").value();
Q_ASSERT(acc);
acc->deleteLater();
}
void SyncDaemon::authenticateAccount(const SyncAccount *account, const QString &serviceName)
{
NotifyMessage *notify = new NotifyMessage(true, this);
notify->setProperty("ACCOUNT", QVariant::fromValue(account->id()));
notify->setProperty("SERVICE", QVariant::fromValue(account->serviceId(serviceName)));
connect(notify, SIGNAL(questionAccepted()), SLOT(runAuthentication()));
notify->askYesOrNo(_("Synchronization"),
QString(_("Your access key is not valid anymore. Do you want to re-authenticate it?.")),
account->iconName(serviceName));
}
void SyncDaemon::runAuthentication()
{
QObject *sender = QObject::sender();
AccountId accountId = sender->property("ACCOUNT").value();
QString serviceName = sender->property("SERVICE").value();
QString appCommand = QString("syncmonitorhelper:///authenticate?id=%1&service=%2").arg(accountId).arg(serviceName);
qDebug() << "Run" << appCommand;
url_dispatch_send(appCommand.toUtf8().constData(), NULL, NULL);
}
void SyncDaemon::onAccountSyncStarted(const QString &serviceName, bool firstSync)
{
SyncAccount *acc = qobject_cast(QObject::sender());
if (firstSync) {
NotifyMessage *notify = new NotifyMessage(true, this);
notify->show(_("Synchronization"),
QString(_("Start sync: %1 (%2)"))
.arg(acc->displayName())
.arg(serviceName),
acc->iconName(serviceName));
}
m_syncElapsedTime.restart();
qDebug() << QString("[%3] Start sync: %1 (%2)")
.arg(acc->displayName())
.arg(serviceName)
.arg(QDateTime::currentDateTime().toString(Qt::SystemLocaleShortDate));
Q_EMIT syncStarted(acc, serviceName);
}
void SyncDaemon::onAccountSyncError(const QString &serviceName, const QString &error)
{
Q_EMIT syncError(qobject_cast(QObject::sender()), serviceName, error);
onAccountSyncFinished(serviceName, false, error, "fast");
}
void SyncDaemon::onAccountSyncFinished(const QString &serviceName, const bool firstSync, const QString &status, const QString &mode)
{
// error on that list will trigger a new sync
static QStringList whiteListStatus;
uint errorCode = status.toUInt();
SyncAccount *acc = qobject_cast(QObject::sender());
QString errorMessage = SyncAccount::statusDescription(status);
if (firstSync && errorMessage.isEmpty()) {
NotifyMessage *notify = new NotifyMessage(true, this);
notify->show(_("Synchronization"),
QString(_("Sync done: %1 (%2)"))
.arg(acc->displayName())
.arg(serviceName),
acc->iconName(serviceName));
}
Q_EMIT syncFinished(acc, serviceName);
qDebug() << QString("[%6] Sync done: %1 (%2) Status: %3 Error: %4 Duration: %5s")
.arg(acc->displayName())
.arg(serviceName)
.arg(status)
.arg(errorMessage.isEmpty() ? "None" : errorMessage)
.arg((m_syncElapsedTime.elapsed() < 1000 ? 1 : m_syncElapsedTime.elapsed() / 1000))
.arg(QDateTime::currentDateTime().toString(Qt::SystemLocaleShortDate));
// populate white list erros
if (whiteListStatus.isEmpty()) {
// "error code from SyncEvolution access denied (remote, status 403): could not obtain OAuth2 token:
// this can happen if the network goes off during the sync, or syc started before the network stabilished
whiteListStatus << QStringLiteral("10403");
whiteListStatus << QStringLiteral("403");
// error code from SyncEvolution fatal error (local, status 10500): no sources active, check configuration"
// this is a bug on SyncEvolution sometimes it fail to read the correct address book
// FIXME: we should fix that on SyncEvolution
whiteListStatus << QStringLiteral("10500");
}
// only re-sync if sync mode != "slow", to avoid sync loops
if ((acc->lastError() == 0) && !errorMessage.isEmpty() && whiteListStatus.contains(status)) {
// white list error retry the sync
m_syncQueue->push(acc, serviceName, false);
} else if (status.endsWith("403")){
authenticateAccount(acc, serviceName);
errorCode = 0;
} else if (!errorMessage.isEmpty()) {
NotifyMessage *notify = new NotifyMessage(true, this);
notify->show(_("Synchronization"),
QString(_("Fail to sync %1 (%2).\n%3"))
.arg(acc->displayName())
.arg(serviceName)
.arg(errorMessage),
acc->iconName(serviceName));
}
acc->setLastError(errorCode);
// sync next account
continueSync();
}
void SyncDaemon::onAccountEnableChanged(const QString &serviceName, bool enabled)
{
SyncAccount *acc = qobject_cast(QObject::sender());
if (enabled) {
sync(acc, serviceName, true);
} else {
cancel(acc, serviceName);
}
Q_EMIT accountsChanged();
}
void SyncDaemon::onAccountConfigured(const QString &serviceName)
{
SyncAccount *acc = qobject_cast(QObject::sender());
m_eds->createSource(serviceName, acc->displayName());
}
void SyncDaemon::quit()
{
m_aboutToQuit = true;
if (m_dbusAddaptor) {
delete m_dbusAddaptor;
m_dbusAddaptor = 0;
}
if (m_eds) {
delete m_eds;
m_eds = 0;
}
// cancel all sync operation
while(m_syncQueue->count()) {
SyncJob job = m_syncQueue->popNext();
SyncAccount *acc = job.account();
acc->cancel();
acc->wait();
delete acc;
}
while(m_offlineQueue->count()) {
SyncJob job = m_offlineQueue->popNext();
SyncAccount *acc = job.account();
acc->cancel();
acc->wait();
delete acc;
}
if (m_manager) {
delete m_manager;
m_manager = 0;
}
if (m_networkStatus) {
delete m_networkStatus;
}
}
sync-monitor-0.2+16.04.20160304/src/syncevolution-server-proxy.cpp 0000644 0000156 0000165 00000005075 12666332064 025272 0 ustar pbuser pbgroup 0000000 0000000 /*
* Copyright 2014 Canonical Ltd.
*
* This file is part of sync-monitor.
*
* sync-monitor 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; version 3.
*
* contact-service-app 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 .
*/
#include "syncevolution-server-proxy.h"
#include "syncevolution-session-proxy.h"
#include
#include
#define SYNCEVOLUTION_SERVICE_NAME "org.syncevolution"
#define SYNCEVOLUTION_OBJECT_PATH "/org/syncevolution/Server"
#define SYNCEVOLUTION_IFACE_NAME "org.syncevolution.Server"
SyncEvolutionServerProxy *SyncEvolutionServerProxy::m_instance = 0;
SyncEvolutionServerProxy::SyncEvolutionServerProxy(QObject *parent)
: QObject(parent)
{
m_iface = new QDBusInterface(SYNCEVOLUTION_SERVICE_NAME,
SYNCEVOLUTION_OBJECT_PATH,
SYNCEVOLUTION_IFACE_NAME);
}
SyncEvolutionServerProxy::~SyncEvolutionServerProxy()
{
if (m_iface) {
m_iface->call("Detach");
m_iface->deleteLater();
m_iface = 0;
}
}
SyncEvolutionServerProxy *SyncEvolutionServerProxy::instance()
{
if (!m_instance) {
m_instance = new SyncEvolutionServerProxy();
}
return m_instance;
}
void SyncEvolutionServerProxy::destroy()
{
if (m_instance) {
delete m_instance;
m_instance = 0;
}
}
SyncEvolutionSessionProxy* SyncEvolutionServerProxy::openSession(const QString &sessionName,
QStringList flags)
{
QDBusReply reply;
if (flags.isEmpty()) {
reply = m_iface->call("StartSession", sessionName);
} else {
reply = m_iface->call("StartSessionWithFlags", sessionName, flags);
}
if (m_iface->lastError().isValid()) {
qWarning() << "Fail to start session" << m_iface->lastError().message();
return 0;
}
return new SyncEvolutionSessionProxy(reply.value(), this);
}
QStringList SyncEvolutionServerProxy::configs(bool templates) const
{
QDBusReply reply = m_iface->call("GetConfigs", templates);
return reply.value();
}
sync-monitor-0.2+16.04.20160304/src/notify-message-mock.cpp 0000644 0000156 0000165 00000000427 12666332064 023543 0 ustar pbuser pbgroup 0000000 0000000 #include "notify-message.h"
#include
NotifyMessage::NotifyMessage()
{
}
NotifyMessage::~NotifyMessage()
{
}
void NotifyMessage::show(const QString &title, const QString &msg, const QString &icon)
{
Q_UNUSED(icon);
qDebug() << title << "\t" << msg;
}
sync-monitor-0.2+16.04.20160304/src/notify-message.cpp 0000644 0000156 0000165 00000010271 12666332064 022612 0 ustar pbuser pbgroup 0000000 0000000 /*
* Copyright 2014 Canonical Ltd.
*
* This file is part of sync-monitor.
*
* sync-monitor 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; version 3.
*
* contact-service-app 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 .
*/
#include "notify-message.h"
#include "sync-i18n.h"
#include
#include
int NotifyMessage::m_instanceCount = 0;
NotifyMessage::NotifyMessage(bool singleMessage, QObject *parent)
: QObject(parent),
m_notification(0),
m_singleMessage(singleMessage)
{
if (m_instanceCount == 0) {
m_instanceCount++;
notify_init(QCoreApplication::instance()->applicationName().toUtf8());
}
}
NotifyMessage::~NotifyMessage()
{
if (m_notification) {
g_object_unref(m_notification);
m_notification = 0;
}
m_instanceCount--;
if (m_instanceCount == 0) {
notify_uninit();
}
}
void NotifyMessage::show(const QString &title, const QString &msg, const QString &iconName)
{
m_notification = notify_notification_new(title.toUtf8().data(),
msg.toUtf8().data(),
iconName.isEmpty() ? (const char*) 0 : iconName.toUtf8().constData());
notify_notification_set_timeout(m_notification, NOTIFY_EXPIRES_DEFAULT);
notify_notification_show(m_notification, 0);
g_signal_connect_after(m_notification,
"closed",
(GCallback) NotifyMessage::onNotificationClosed,
this);
}
void NotifyMessage::askYesOrNo(const QString &title,
const QString &msg,
const QString &iconName)
{
m_notification = notify_notification_new(title.toUtf8().data(),
msg.toUtf8().data(),
iconName.isEmpty() ? (const char*) 0 : iconName.toUtf8().constData());
notify_notification_set_hint_string(m_notification,
"x-canonical-snap-decisions",
"true");
notify_notification_set_hint_string(m_notification,
"x-canonical-private-button-tint",
"true");
notify_notification_set_hint_string(m_notification,
"x-canonical-non-shaped-icon",
"true");
notify_notification_add_action(m_notification,
"action_accept", _("Yes"),
(NotifyActionCallback) NotifyMessage::onQuestionAccepted,
this,
NULL);
notify_notification_add_action(m_notification,
"action_reject", _("No"),
(NotifyActionCallback) NotifyMessage::onQuestionRejected,
this,
NULL);
notify_notification_show(m_notification, 0);
g_signal_connect_after(m_notification,
"closed",
(GCallback) NotifyMessage::onNotificationClosed,
this);
}
void NotifyMessage::onQuestionAccepted(NotifyNotification *notification, char *action, NotifyMessage *self)
{
Q_EMIT self->questionAccepted();
}
void NotifyMessage::onQuestionRejected(NotifyNotification *notification, char *action, NotifyMessage *self)
{
Q_EMIT self->questionRejected();
}
void NotifyMessage::onNotificationClosed(NotifyNotification *notification, NotifyMessage *self)
{
Q_EMIT self->messageClosed();
if (self->m_singleMessage) {
self->deleteLater();
}
}
sync-monitor-0.2+16.04.20160304/src/sync-i18n.h 0000644 0000156 0000165 00000001511 12666332064 021053 0 ustar pbuser pbgroup 0000000 0000000 /*
* Copyright 2014 Canonical Ltd.
*
* This file is part of sync-monitor.
*
* sync-monitor 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; version 3.
*
* contact-service-app 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 .
*/
#ifndef __SYNC_I18N_H__
#define __SYNC_I18N_H__
#include "config.h"
extern "C" {
#include
#define _(String) dgettext (GETTEXT_PACKAGE, String)
}
#endif
sync-monitor-0.2+16.04.20160304/src/sync-dbus.h 0000644 0000156 0000165 00000007575 12666332064 021251 0 ustar pbuser pbgroup 0000000 0000000 /*
* Copyright 2014 Canonical Ltd.
*
* This file is part of sync-monitor.
*
* sync-monitor 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; version 3.
*
* contact-service-app 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 .
*/
#ifndef __SYNC_DBUS_H__
#define __SYNC_DBUS_H__
#include "dbustypes.h"
#include
#include
#include
#define SYNCMONITOR_SERVICE_NAME "com.canonical.SyncMonitor"
#define SYNCMONITOR_OBJECT_PATH "/com/canonical/SyncMonitor"
class SyncDaemon;
class SyncAccount;
class SyncDBus : public QDBusAbstractAdaptor
{
Q_OBJECT
Q_CLASSINFO("D-Bus Interface", SYNCMONITOR_SERVICE_NAME)
Q_CLASSINFO("D-Bus Introspection", ""
" \n"
" \n"
" \n"
" \n"
" \n"
" \n"
" \n"
" \n"
" \n"
" \n"
" \n"
" \n"
" \n"
" \n"
" \n"
" \n"
" \n"
" \n"
" \n"
" \n"
" \n"
" \n"
" \n"
" \n"
" \n"
" \n"
" \n"
" \n"
" \n"
" \n"
" \n"
" \n"
" \n"
" \n"
"")
Q_PROPERTY(QString state READ state NOTIFY stateChanged)
Q_PROPERTY(QStringList enabledServices READ enabledServices NOTIFY enabledServicesChanged)
public:
SyncDBus(const QDBusConnection &connection, SyncDaemon *parent);
bool start();
Q_SIGNALS:
void syncStarted(const QString &account, const QString &service);
void syncFinished(const QString &account, const QString &service);
void syncError(const QString &account, const QString &service, const QString &error);
void stateChanged();
void enabledServicesChanged();
void clientAttached(int count);
void clientDeattached(int count);
public Q_SLOTS:
void sync(QStringList service);
void syncAccount(quint32 accountId, const QString &service);
void cancel(QStringList services);
QString state() const;
QStringList enabledServices() const;
QStringList servicesAvailable();
void attach();
void detach();
private Q_SLOTS:
void onSyncStarted(SyncAccount *syncAcc, const QString &serviceName);
void onSyncFinished(SyncAccount *syncAcc, const QString &serviceName);
void onSyncError(SyncAccount *syncAcc, const QString &serviceName, const QString &error);
void updateState();
private:
SyncDaemon *m_parent;
QDBusConnection m_connection;
QString m_state;
int m_clientCount;
};
#endif
sync-monitor-0.2+16.04.20160304/src/sync-network.h 0000644 0000156 0000165 00000002703 12666332064 021771 0 ustar pbuser pbgroup 0000000 0000000 /*
* Copyright 2014 Canonical Ltd.
*
* This file is part of sync-monitor.
*
* sync-monitor 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; version 3.
*
* contact-service-app 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 .
*/
#ifndef __SYNC_NETWORK_H__
#define __SYNC_NETWORK_H__
#include
#include
#include
class SyncNetwork : public QObject
{
Q_OBJECT
Q_PROPERTY(NetworkState state READ state NOTIFY stateChanged)
public:
enum NetworkState {
NetworkOffline = 0,
NetworkPartialOnline,
NetworkOnline
};
SyncNetwork(QObject *parent=0);
~SyncNetwork();
NetworkState state() const;
void setState(NetworkState newState);
Q_SIGNALS:
void stateChanged(SyncNetwork::NetworkState state);
private Q_SLOTS:
void refresh();
void idleRefresh();
private:
QScopedPointer m_configManager;
NetworkState m_state;
QTimer m_idleRefresh;
};
#endif
sync-monitor-0.2+16.04.20160304/src/main.cpp 0000644 0000156 0000165 00000003054 12666332064 020605 0 ustar pbuser pbgroup 0000000 0000000 /*
* Copyright 2014 Canonical Ltd.
*
* This file is part of sync-monitor.
*
* sync-monitor 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; version 3.
*
* contact-service-app 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 .
*/
#include "sync-daemon.h"
#include "dbustypes.h"
#include
#include
#include
namespace C {
#include
}
#include "config.h"
int main(int argc, char** argv)
{
// register all syncevolution dbus types
syncevolution_qt_dbus_register_types();
QCoreApplication app(argc, argv);
app.setApplicationName("sync-monitor");
setlocale(LC_ALL, "");
C::bindtextdomain(GETTEXT_PACKAGE, GETTEXT_LOCALEDIR);
C::bind_textdomain_codeset(GETTEXT_PACKAGE, "UTF-8");
SyncDaemon *daemon = new SyncDaemon();
qputenv("QORGANIZER_EDS_DEBUG", "on");
daemon->connect(&app, SIGNAL(aboutToQuit()), SLOT(quit()));
daemon->run();
if ((argc == 2) && (strcmp(argv[1], "--sync") == 0)) {
qDebug() << "Start manual sync";
QTimer::singleShot(1000, daemon, SLOT(syncAll()));
}
return app.exec();
}
sync-monitor-0.2+16.04.20160304/src/syncevolution-server-proxy.h 0000644 0000156 0000165 00000002576 12666332064 024742 0 ustar pbuser pbgroup 0000000 0000000 /*
* Copyright 2014 Canonical Ltd.
*
* This file is part of sync-monitor.
*
* sync-monitor 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; version 3.
*
* contact-service-app 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 .
*/
#ifndef __SYNCEVOLUTION_SERVER_PROXY_H__
#define __SYNCEVOLUTION_SERVER_PROXY_H__
#include "dbustypes.h"
#include
#include
#include
#include
class SyncEvolutionSessionProxy;
class SyncEvolutionServerProxy : public QObject
{
Q_OBJECT
public:
static SyncEvolutionServerProxy *instance();
static void destroy();
SyncEvolutionSessionProxy *openSession(const QString &sessionName, QStringList flags);
QStringList configs(bool templates=false) const;
private:
static SyncEvolutionServerProxy *m_instance;
QDBusInterface *m_iface;
SyncEvolutionServerProxy(QObject *parent = 0);
~SyncEvolutionServerProxy();
};
#endif
sync-monitor-0.2+16.04.20160304/src/eds-helper.h 0000644 0000156 0000165 00000005260 12666332064 021357 0 ustar pbuser pbgroup 0000000 0000000 /*
* Copyright 2014 Canonical Ltd.
*
* This file is part of sync-monitor.
*
* sync-monitor 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; version 3.
*
* contact-service-app 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 .
*/
#ifndef __EDS_HELPER_H__
#define __EDS_HELPER_H__
#include
#include
#include
#include
#include
#include
#include
#include
// necessary for singna/slot signatures;
using namespace QtContacts;
using namespace QtOrganizer;
class EdsHelper : public QObject
{
Q_OBJECT
public:
EdsHelper(QObject *parent = 0,
const QString &contactManager = "galera",
const QString &organizerManager = "eds");
~EdsHelper();
void createSource(const QString &serviceName, const QString &sourceName);
void removeSource(const QString &serviceName, const QString &sourceName);
void freezeNotify();
void unfreezeNotify();
void flush();
void setEnabled(bool enabled);
Q_SIGNALS:
void dataChanged(const QString &serviceName, const QString &sourceName);
private Q_SLOTS:
void contactChangedFilter(const QList& contactIds);
void contactChanged(const QString &sourceName = QString());
void contactDataChanged();
void calendarChanged(const QList &itemIds);
void contactFetchStateChanged(QContactAbstractRequest::State newState);
void calendarCollectionsChanged();
protected:
QtOrganizer::QOrganizerManager *m_organizerEngine;
QtContacts::QContactManager *m_contactEngine;
virtual QString getCollectionIdFromItemId(const QtOrganizer::QOrganizerItemId &itemId) const;
private:
QTimer m_timeoutTimer;
bool m_freezed;
// cache calendar collections
QList m_calendarCollections;
QSet m_pendingContacts;
QSet m_pendingCalendars;
void createOrganizerSource(const QString &sourceName);
void createContactsSource(const QString &sourceName);
void removeOrganizerSource(const QString &sourceName);
void removeContactsSource(const QString &sourceName);
};
#endif
sync-monitor-0.2+16.04.20160304/src/eds-helper.cpp 0000644 0000156 0000165 00000027047 12666332070 021716 0 ustar pbuser pbgroup 0000000 0000000 #include "eds-helper.h"
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include "config.h"
#define CHANGE_TIMEOUT 3000
using namespace QtOrganizer;
using namespace QtContacts;
EdsHelper::EdsHelper(QObject *parent,
const QString &contactManager,
const QString &organizerManager)
: QObject(parent),
m_freezed(false)
{
qRegisterMetaType >("QList");
qRegisterMetaType >("QList");
if (!contactManager.isEmpty()) {
m_contactEngine = new QContactManager(contactManager, QMap());
} else {
m_contactEngine = 0;
}
if (!organizerManager.isEmpty()) {
m_organizerEngine = new QOrganizerManager(organizerManager, QMap());
} else {
m_organizerEngine = 0;
}
m_timeoutTimer.setSingleShot(true);
}
EdsHelper::~EdsHelper()
{
delete m_contactEngine;
delete m_organizerEngine;
}
void EdsHelper::createSource(const QString &serviceName, const QString &sourceName)
{
if (serviceName == CONTACTS_SERVICE_NAME) {
createContactsSource(sourceName);
} else if (serviceName == CALENDAR_SERVICE_NAME) {
createOrganizerSource(sourceName);
} else {
qWarning() << "Service not supported:" << serviceName;
}
}
void EdsHelper::removeSource(const QString &serviceName, const QString &sourceName)
{
if (serviceName.isEmpty() || (serviceName == CONTACTS_SERVICE_NAME)) {
removeContactsSource(sourceName);
}
if (serviceName.isEmpty() || (serviceName == CALENDAR_SERVICE_NAME)) {
removeOrganizerSource(sourceName);
}
}
void EdsHelper::freezeNotify()
{
m_freezed = true;
}
void EdsHelper::unfreezeNotify()
{
m_pendingContacts.clear();
m_pendingCalendars.clear();
m_freezed = false;
m_timeoutTimer.start(CHANGE_TIMEOUT);
}
void EdsHelper::flush()
{
m_freezed = false;
contactChangedFilter(m_pendingContacts.toList());
m_pendingContacts.clear();
Q_FOREACH(const QString &calendar, m_pendingCalendars) {
Q_EMIT dataChanged(CALENDAR_SERVICE_NAME, calendar);
}
m_pendingCalendars.clear();
}
void EdsHelper::setEnabled(bool enabled)
{
if (enabled) {
if (m_contactEngine) {
connect(m_contactEngine,
SIGNAL(contactsAdded(QList)),
SLOT(contactChangedFilter(QList)),
Qt::QueuedConnection);
connect(m_contactEngine,
SIGNAL(contactsChanged(QList)),
SLOT(contactChangedFilter(QList)),
Qt::QueuedConnection);
connect(m_contactEngine,
SIGNAL(contactsRemoved(QList)),
SLOT(contactChanged()),
Qt::QueuedConnection);
connect(m_contactEngine,
SIGNAL(dataChanged()),
SLOT(contactDataChanged()),
Qt::QueuedConnection);
}
if (m_organizerEngine) {
connect(m_organizerEngine,
SIGNAL(itemsAdded(QList)),
SLOT(calendarChanged(QList)), Qt::QueuedConnection);
connect(m_organizerEngine,
SIGNAL(itemsRemoved(QList)),
SLOT(calendarChanged(QList)), Qt::QueuedConnection);
connect(m_organizerEngine,
SIGNAL(itemsChanged(QList)),
SLOT(calendarChanged(QList)), Qt::QueuedConnection);
connect(m_organizerEngine,
SIGNAL(collectionsModified(QList >)),
SLOT(calendarCollectionsChanged()));
}
} else {
if (m_contactEngine) {
m_contactEngine->disconnect(this);
}
if (m_organizerEngine) {
m_organizerEngine->disconnect(this);
}
}
}
void EdsHelper::contactChangedFilter(const QList& contactIds)
{
Q_ASSERT(m_contactEngine);
if (m_freezed) {
m_pendingContacts += contactIds.toSet();
} else {
QContactFetchByIdRequest *request = new QContactFetchByIdRequest(m_contactEngine);
request->setManager(m_contactEngine);
request->setIds(contactIds);
QContactFetchHint hint;
hint.setDetailTypesHint(QList() << QContactDetail::TypeSyncTarget);
request->setFetchHint(hint);
connect(request, SIGNAL(stateChanged(QContactAbstractRequest::State)),
SLOT(contactFetchStateChanged(QContactAbstractRequest::State)));
request->start();
}
}
void EdsHelper::contactFetchStateChanged(QContactAbstractRequest::State newState)
{
Q_ASSERT(m_contactEngine);
if ((newState == QContactAbstractRequest::ActiveState) ||
(newState == QContactAbstractRequest::InactiveState)) {
return;
}
QContactFetchByIdRequest *request = qobject_cast(QObject::sender());
if (newState == QContactAbstractRequest::FinishedState) {
QSet sources;
Q_FOREACH(const QContact &contact, request->contacts()) {
QContactSyncTarget syncTarget = contact.detail();
if (!syncTarget.syncTarget().isEmpty()) {
sources << syncTarget.syncTarget();
}
}
Q_FOREACH(const QString &source, sources) {
contactChanged(source);
}
}
request->deleteLater();
}
void EdsHelper::calendarCollectionsChanged()
{
m_calendarCollections.clear();
}
QString EdsHelper::getCollectionIdFromItemId(const QOrganizerItemId &itemId) const
{
return itemId.toString().split("/").first();
}
void EdsHelper::contactChanged(const QString& sourceName)
{
if (!m_timeoutTimer.isActive()) {
Q_EMIT dataChanged(CONTACTS_SERVICE_NAME, sourceName);
} else {
qDebug() << "Ignore contact changed:" << sourceName;
}
}
void EdsHelper::contactDataChanged()
{
// The dataChanged signal is fired during the server startup.
// Some contact data is loaded async like Avatar, a signal with contactChanged will be fired
// late during the server startup. Because of that We will wait for some time before start to
// accept contact changes signals, to avoid unnecessary syncs.
m_timeoutTimer.start(CHANGE_TIMEOUT);
}
void EdsHelper::calendarChanged(const QList &itemIds)
{
Q_ASSERT(m_organizerEngine);
QSet uniqueColletions;
// eds item ids cotains the collection id we can use that instead of query for the full item
Q_FOREACH(const QOrganizerItemId &id, itemIds) {
uniqueColletions << getCollectionIdFromItemId(id);
}
if (uniqueColletions.isEmpty()) {
return;
}
if (m_calendarCollections.isEmpty()) {
m_calendarCollections = m_organizerEngine->collections();
}
Q_FOREACH(const QString &collectionId, uniqueColletions) {
Q_FOREACH(const QOrganizerCollection &collection, m_calendarCollections) {
if (collection.id().toString() == collectionId) {
QString collectionName = collection.metaData(QOrganizerCollection::KeyName).toString();
if (m_freezed) {
m_pendingCalendars << collectionName;
} else {
Q_EMIT dataChanged(CALENDAR_SERVICE_NAME, collectionName);
}
break;
}
}
}
}
void EdsHelper::createContactsSource(const QString &sourceName)
{
if (!m_contactEngine) {
qWarning() << "Request to create contact source with null engine";
return;
}
// filter all contact groups/addressbook
QContactDetailFilter filter;
filter.setDetailType(QContactDetail::TypeType, QContactType::FieldType);
filter.setValue(QContactType::TypeGroup);
// check if the source already exists
QList sources = m_contactEngine->contacts(filter);
Q_FOREACH(const QContact &contact, sources) {
if (contact.detail().label() == sourceName) {
return;
}
}
// create a new source
QContact contact;
contact.setType(QContactType::TypeGroup);
QContactDisplayLabel label;
label.setLabel(sourceName);
contact.saveDetail(&label);
// set the new source as default if there is only the local source
if (sources.size() == 1) {
QContactExtendedDetail isDefault;
isDefault.setName("IS-PRIMARY");
isDefault.setData(true);
contact.saveDetail(&isDefault);
}
if (!m_contactEngine->saveContact(&contact)) {
qWarning() << "Fail to create contact source:" << sourceName;
}
}
void EdsHelper::removeOrganizerSource(const QString &sourceName)
{
if (!m_organizerEngine) {
qWarning() << "Request to remove organizer source with a null organize engine";
return;
}
QOrganizerCollectionId collectionId;
QList result = m_organizerEngine->collections();
Q_FOREACH(const QOrganizerCollection &collection, result) {
if (collection.metaData(QOrganizerCollection::KeyName).toString() == sourceName) {
collectionId = collection.id();
break;
}
}
if (!collectionId.isNull()) {
if (!m_organizerEngine->removeCollection(collectionId)) {
qWarning() << "Fail to remove calendar source" << sourceName;
}
} else {
qWarning() << "Calendar source not found" << sourceName;
}
}
void EdsHelper::removeContactsSource(const QString &sourceName)
{
if (!m_contactEngine) {
qWarning() << "Request to remove contact source with a null contact engine";
return;
}
// check source Id
QContactId sourceId;
QContactDetailFilter filter;
filter.setDetailType(QContactDetail::TypeType, QContactType::FieldType);
filter.setValue(QContactType::TypeGroup);
// check if the source already exists
QList sources = m_contactEngine->contacts(filter);
Q_FOREACH(const QContact &contact, sources) {
if (contact.detail().label() == sourceName) {
sourceId = contact.id();
break;
}
}
if (sourceId.isNull() || !m_contactEngine->removeContact(sourceId)) {
qWarning() << "Fail to remove contact source:" << sourceName;
}
}
void EdsHelper::createOrganizerSource(const QString &sourceName)
{
if (!m_organizerEngine) {
qWarning() << "Request to create an organizer source with a null organize engine";
return;
}
QList result = m_organizerEngine->collections();
Q_FOREACH(const QOrganizerCollection &collection, result) {
if (collection.metaData(QOrganizerCollection::KeyName).toString() == sourceName) {
return;
}
}
QOrganizerCollection collection;
collection.setMetaData(QOrganizerCollection::KeyName, sourceName);
collection.setExtendedMetaData("collection-selected", true);
if (!m_organizerEngine->saveCollection(&collection)) {
qWarning() << "Fail to create collection" << sourceName;
}
}
sync-monitor-0.2+16.04.20160304/src/sync-daemon.h 0000644 0000156 0000165 00000007047 12666332064 021551 0 ustar pbuser pbgroup 0000000 0000000 /*
* Copyright 2014 Canonical Ltd.
*
* This file is part of sync-monitor.
*
* sync-monitor 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; version 3.
*
* contact-service-app 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 .
*/
#ifndef __SYNC_DAEMON_H__
#define __SYNC_DAEMON_H__
#include
#include
#include
#include
#include
#include "sync-network.h"
class SyncAccount;
class EdsHelper;
class ProviderTemplate;
class SyncQueue;
class SyncDBus;
class SyncDaemon : public QObject
{
Q_OBJECT
public:
SyncDaemon();
~SyncDaemon();
void run();
bool isPending() const;
bool isSyncing() const;
QStringList availableServices() const;
QStringList enabledServices() const;
bool isOnline() const;
Q_SIGNALS:
void syncStarted(SyncAccount *syncAcc, const QString &serviceName);
void syncFinished(SyncAccount *syncAcc, const QString &serviceName);
void syncError(SyncAccount *syncAcc, const QString &serviceName, const QString &error);
void syncAboutToStart();
void done();
void accountsChanged();
void isOnlineChanged(bool isOnline);
public Q_SLOTS:
void quit();
void syncAll(const QString &serviceName = QString(), bool runNow=false);
void syncAccount(quint32 accountId, const QString &service);
void cancel(const QString &serviceName = QString());
private Q_SLOTS:
void continueSync();
void addAccount(const Accounts::AccountId &accountId, bool startSync=true);
void removeAccount(const Accounts::AccountId &accountId);
void destroyAccount();
void authenticateAccount(const SyncAccount *account,
const QString &serviceName);
void runAuthentication();
void onAccountSyncStarted(const QString &serviceName, bool firstSync);
void onAccountSyncFinished(const QString &serviceName, bool firstSync, const QString &status, const QString &syncMode);
void onAccountSyncError(const QString &serviceName, const QString &error);
void onAccountEnableChanged(const QString &serviceName, bool enabled);
void onAccountConfigured(const QString &serviceName);
void onDataChanged(const QString &serviceName, const QString &sourceName);
void onClientAttached();
void onOnlineStatusChanged(SyncNetwork::NetworkState state);
private:
Accounts::Manager *m_manager;
QTimer *m_timeout;
QHash m_accounts;
SyncQueue *m_syncQueue;
SyncQueue *m_offlineQueue;
SyncAccount *m_currentAccount;
QString m_currentServiceName;
EdsHelper *m_eds;
ProviderTemplate *m_provider;
SyncDBus *m_dbusAddaptor;
SyncNetwork *m_networkStatus;
bool m_syncing;
bool m_aboutToQuit;
QElapsedTimer m_syncElapsedTime;
bool m_firstClient;
void setupAccounts();
void setupTriggers();
void sync(SyncAccount *syncAcc, const QString &serviceName = QString(), bool runNow = false);
void cancel(SyncAccount *syncAcc, const QString &serviceName = QString());
void setup();
void sync(bool runNow);
bool registerService();
void syncFinishedImpl();
};
#endif
sync-monitor-0.2+16.04.20160304/src/sync-configure.cpp 0000644 0000156 0000165 00000021722 12666332064 022616 0 ustar pbuser pbgroup 0000000 0000000 /*
* Copyright 2014 Canonical Ltd.
*
* This file is part of sync-monitor.
*
* sync-monitor 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; version 3.
*
* contact-service-app 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 .
*/
#include "sync-configure.h"
#include "syncevolution-server-proxy.h"
#include "syncevolution-session-proxy.h"
#include "config.h"
using namespace Accounts;
SyncConfigure::SyncConfigure(Accounts::Account *account,
QSettings *settings,
QObject *parent)
: QObject(parent),
m_account(account),
m_settings(settings)
{
}
SyncConfigure::~SyncConfigure()
{
Q_ASSERT(m_sessions.size() == 0);
}
void SyncConfigure::configure(const QString &serviceName, const QString &syncMode)
{
m_syncMode = syncMode;
m_originalServiceName = serviceName;
if (serviceName.isEmpty()) {
configureAll(syncMode);
} else {
m_services << serviceName;
configureServices(syncMode);
}
}
void SyncConfigure::configureAll(const QString &syncMode)
{
Q_FOREACH(Service service, m_account->services()) {
m_services << service.serviceType();
}
configureServices(syncMode);
}
QString SyncConfigure::serviceName() const
{
return m_originalServiceName;
}
void SyncConfigure::configureServices(const QString &syncMode)
{
SyncEvolutionServerProxy *proxy = SyncEvolutionServerProxy::instance();
qDebug() << "start configure for services" << m_services;
QStringList pendingServices = m_services;
Q_FOREACH(QString serviceName, pendingServices) {
QString sessionName = QString("%1-%2-%3")
.arg(m_account->providerName())
.arg(serviceName)
.arg(m_account->id());
SyncEvolutionSessionProxy *session = proxy->openSession(sessionName,
QStringList() << "all-configs");
m_sessions.insert(serviceName, session);
connect(session, &SyncEvolutionSessionProxy::statusChanged,
this, &SyncConfigure::onSessionStatusChanged);
connect(session, &SyncEvolutionSessionProxy::error,
this, &SyncConfigure::onSessionError);
qDebug() << "\tconfig session created" << sessionName << session->status();
if (session->status() != "queueing") {
configureService(serviceName, syncMode);
}
}
}
void SyncConfigure::configureService(const QString &serviceName, const QString &syncMode)
{
SyncEvolutionServerProxy *proxy = SyncEvolutionServerProxy::instance();
QStringList configs = proxy->configs();
QString targetSuffix = QString("%1-%2-%3")
.arg(m_account->providerName())
.arg(serviceName)
.arg(m_account->id());
QString targetConfigName = QString("target-config@%1").arg(targetSuffix);
bool isConfigured = true;
if (!configs.contains(targetConfigName)) {
qDebug() << "\tCreate target:" << targetConfigName;
isConfigured = configTarget(targetConfigName, serviceName);
}
if (isConfigured && !configs.contains(targetSuffix)) {
qDebug() << "\tCreate sync config:" << targetSuffix;
isConfigured = configSync(targetSuffix, serviceName, syncMode);
} else if (isConfigured) {
isConfigured = changeSyncMode(targetSuffix, serviceName, syncMode);
}
if (!isConfigured) {
qWarning() << "Fail to configure account:" << m_account->displayName() << m_account->id() << serviceName;
}
removeService(serviceName);
}
void SyncConfigure::removeService(const QString &serviceName)
{
m_services.removeOne(serviceName);
SyncEvolutionSessionProxy *session = m_sessions.take(serviceName);
session->destroy();
delete session;
if (m_services.isEmpty()) {
qDebug() << "\taccount config done" << m_account->displayName() << serviceName;
Q_EMIT done();
}
}
bool SyncConfigure::configTarget(const QString &targetName, const QString &serviceName)
{
AccountId accountId = m_account->id();
SyncEvolutionSessionProxy *session = m_sessions.value(serviceName, 0);
// loas settings
m_settings->beginGroup(serviceName);
QString templateName = m_settings->value("template", "SyncEvolution").toString();
QString syncUrl = m_settings->value("syncURL", QString(QString::null)).toString();
QString uoaServiceName = m_settings->value("uoa-service", "").toString();
m_settings->endGroup();
// config server side
Q_ASSERT(!templateName.isEmpty());
QStringMultiMap config = session->getConfig(templateName, true);
if (!syncUrl.isNull()) {
config[""]["syncURL"] = syncUrl;
}
config[""]["username"] = QString("uoa:%1,%2").arg(accountId).arg(uoaServiceName);
config[""]["consumerReady"] = "0";
config[""]["dumpData"] = "0";
config[""]["printChanges"] = "0";
config[""]["maxlogdirs"] = "2";
QString expectedSource;
bool isCalendar = false;
if (serviceName == CONTACTS_SERVICE_NAME) {
expectedSource = QString("source/addressbook");
} else if (serviceName == CALENDAR_SERVICE_NAME) {
isCalendar = true;
expectedSource = QString("source/calendar");
} else {
expectedSource = QString("source/%1").arg(serviceName);
}
if (isCalendar) {
// limit the number of retrieve events to optimize the initial query
// 3 months before
config[expectedSource]["syncInterval"] = "90";
}
bool result = session->saveConfig(targetName, config);
if (!result) {
qWarning() << "Fail to save account client config";
return false;
}
return true;
}
bool SyncConfigure::changeSyncMode(const QString &targetName, const QString &serviceName, const QString &syncMode)
{
SyncEvolutionSessionProxy *session = m_sessions.value(serviceName, 0);
QStringMultiMap config = session->getConfig(targetName, false);
Q_ASSERT(!config.isEmpty());
AccountId accountId = m_account->id();
QString sourceName = QString("%1_uoa_%2").arg(serviceName).arg(accountId);
QString sourceFullName = QString("source/%1").arg(sourceName);
config[sourceFullName]["sync"] = syncMode;
bool result = session->saveConfig(targetName, config);
if (!result) {
qWarning() << "Fail to save account client config";
return false;
}
return result;
}
bool SyncConfigure::configSync(const QString &targetName, const QString &serviceName, const QString &syncMode)
{
AccountId accountId = m_account->id();
SyncEvolutionSessionProxy *session = m_sessions.value(serviceName, 0);
m_settings->beginGroup(serviceName);
QString clientBackend = m_settings->value("sync-backend", QString(QString::null)).toString();
QString clientUri = m_settings->value("sync-uri", QString(QString::null)).toString();
m_settings->endGroup();
QStringMultiMap config = session->getConfig("SyncEvolution_Client", true);
Q_ASSERT(!config.isEmpty());
config[""]["syncURL"] = QString("local://@%1").arg(targetName);
config[""]["username"] = QString();
config[""]["password"] = QString();
config[""]["dumpData"] = "0";
config[""]["printChanges"] = "0";
config[""]["maxlogdirs"] = "2";
// remove default sources
config.remove("source/addressbook");
config.remove("source/calendar");
config.remove("source/todo");
config.remove("source/memo");
// database
QString sourceName = QString("%1_uoa_%2").arg(serviceName).arg(accountId);
QString sourceFullName = QString("source/%1").arg(sourceName);
config[sourceFullName]["database"] = m_account->displayName();
if (!clientBackend.isNull()) {
config[sourceFullName]["backend"] = clientBackend;
}
//TODO: create one for each database
if (!clientUri.isNull()) {
config[sourceFullName]["uri"] = clientUri;
}
config[sourceFullName]["sync"] = syncMode;
bool result = session->saveConfig(targetName, config);
if (!result) {
qWarning() << "Fail to save account client config";
return false;
}
return result;
}
void SyncConfigure::onSessionStatusChanged(const QString &newStatus)
{
SyncEvolutionSessionProxy *session = qobject_cast(QObject::sender());
if (newStatus != "queueing") {
configureService(m_sessions.key(session), m_syncMode);
}
}
void SyncConfigure::onSessionError(uint errorCode)
{
SyncEvolutionSessionProxy *session = qobject_cast(QObject::sender());
QString serviceName = m_sessions.key(session);
removeService(serviceName);
Q_UNUSED(errorCode);
Q_EMIT error();
}
sync-monitor-0.2+16.04.20160304/src/sync-account.h 0000644 0000156 0000165 00000007671 12666332064 021745 0 ustar pbuser pbgroup 0000000 0000000 /*
* Copyright 2014 Canonical Ltd.
*
* This file is part of sync-monitor.
*
* sync-monitor 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; version 3.
*
* contact-service-app 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 .
*/
#ifndef __SYNC_ACCOUNT_H__
#define __SYNC_ACCOUNT_H__
#include
#include
#include
#include
#include "dbustypes.h"
class SyncEvolutionSessionProxy;
class SyncConfigure;
class SyncAccount : public QObject
{
Q_OBJECT
public:
enum AccountState {
Configuring = 0,
Syncing,
Idle,
Invalid
};
SyncAccount(Accounts::Account *account,
QSettings *settings,
QObject *parent=0);
SyncAccount(Accounts::Account *account,
const QString &service,
QSettings *settings,
QObject *parent);
virtual ~SyncAccount();
virtual void setup();
void cancel(const QString &serviceName = QString());
void sync(const QString &serviceName = QString());
void wait();
void status() const;
AccountState state() const;
bool enabled() const;
QString displayName() const;
int id() const;
QString iconName(const QString &serviceName) const;
virtual QStringList availableServices() const;
QStringList enabledServices() const;
uint lastError() const;
void setLastError(uint errorCode);
QString serviceId(const QString &serviceName) const;
bool retrySync() const;
void setRetrySync(bool retry);
static QString statusDescription(const QString &status);
Q_SIGNALS:
void stateChanged(AccountState newState);
void syncStarted(const QString &serviceName, bool firstSync);
void syncFinished(const QString &serviceName, bool firstSync, const QString &status, const QString &mode);
void syncError(const QString &serviceName, const QString &syncError);
void enableChanged(const QString &serviceName, bool enable);
void configured(const QString &serviceName);
private Q_SLOTS:
void onAccountConfigured();
void onAccountConfigureError();
void onAccountEnabledChanged(const QString &serviceName, bool enabled);
void onSessionStatusChanged(const QString &newStatus);
void onSessionProgressChanged(int progress);
void onSessionError(uint error);
private:
Accounts::Account *m_account;
SyncEvolutionSessionProxy *m_currentSession;
QSettings *m_settings;
QMap m_availabeServices;
AccountState m_state;
QList m_sessionConnections;
QList m_pendingConfigs;
uint m_lastError;
bool m_retrySync;
// current sync information
QString m_syncMode;
QString m_syncServiceName;
bool m_firstSync;
void configure(const QString &serviceName, const QString &syncMode);
void setState(AccountState state);
void continueSync(const QString &serviceName);
void attachSession(SyncEvolutionSessionProxy *session);
void releaseSession();
QStringMap lastReport(const QString &serviceName) const;
QString syncMode(const QString &serviceName, bool *firstSync) const;
QString lastSyncStatus(const QString &serviceName, QString *lastSyncMode) const;
bool syncService(const QString &serviceName);
void setupServices();
void dumpReport(const QStringMap &report) const;
bool prepareSession(const QString &serviceName);
QString sessionName(const QString &serviceName) const;
QString sourceName(const QString &serviceName) const;
};
#endif
sync-monitor-0.2+16.04.20160304/src/notify-message.h 0000644 0000156 0000165 00000003340 12666332064 022256 0 ustar pbuser pbgroup 0000000 0000000 /*
* Copyright 2014 Canonical Ltd.
*
* This file is part of sync-monitor.
*
* sync-monitor 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; version 3.
*
* contact-service-app 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 .
*/
#include
#include
#include
class NotifyMessage : public QObject
{
Q_OBJECT
public:
NotifyMessage(bool singleMessage, QObject *parent = 0);
~NotifyMessage();
void show(const QString &title, const QString &msg, const QString &iconName);
void askYesOrNo(const QString &title, const QString &msg, const QString &iconName);
Q_SIGNALS:
void questionAccepted();
void questionRejected();
void messageClosed();
private:
NotifyNotification *m_notification;
bool m_singleMessage;
static int m_instanceCount;
static void onQuestionAccepted(NotifyNotification *notification,
char *action,
NotifyMessage *self);
static void onQuestionRejected(NotifyNotification *notification,
char *action,
NotifyMessage *self);
static void onNotificationClosed(NotifyNotification *notification,
NotifyMessage *self);
};
sync-monitor-0.2+16.04.20160304/src/sync-network.cpp 0000644 0000156 0000165 00000005320 12666332064 022322 0 ustar pbuser pbgroup 0000000 0000000 #include "sync-network.h"
#include
#include
SyncNetwork::SyncNetwork(QObject *parent)
: QObject(parent),
m_configManager(new QNetworkConfigurationManager(this)),
m_state(SyncNetwork::NetworkOffline)
{
refresh();
connect(m_configManager.data(),
SIGNAL(onlineStateChanged(bool)),
SLOT(refresh()), Qt::QueuedConnection);
connect(m_configManager.data(),
SIGNAL(configurationAdded(QNetworkConfiguration)),
SLOT(refresh()), Qt::QueuedConnection);
connect(m_configManager.data(),
SIGNAL(configurationChanged(QNetworkConfiguration)),
SLOT(refresh()), Qt::QueuedConnection);
connect(m_configManager.data(),
SIGNAL(configurationRemoved(QNetworkConfiguration)),
SLOT(refresh()), Qt::QueuedConnection);
connect(m_configManager.data(),
SIGNAL(updateCompleted()),
SLOT(refresh()), Qt::QueuedConnection);
m_idleRefresh.setSingleShot(true);
connect(&m_idleRefresh,
SIGNAL(timeout()),
SLOT(idleRefresh()));
}
SyncNetwork::~SyncNetwork()
{
}
SyncNetwork::NetworkState SyncNetwork::state() const
{
return m_state;
}
void SyncNetwork::setState(SyncNetwork::NetworkState newState)
{
if (m_state != newState) {
m_state = newState;
qDebug() << "Network state changed:" << (m_state == SyncNetwork::NetworkOffline ? "Offline" :
m_state == SyncNetwork::NetworkPartialOnline ? "Partial online" : "Online");
Q_EMIT stateChanged(m_state);
}
}
void SyncNetwork::refresh()
{
m_idleRefresh.start(3000);
}
void SyncNetwork::idleRefresh()
{
// Check if is online
QList activeConfigs = m_configManager->allConfigurations(QNetworkConfiguration::Active);
SyncNetwork::NetworkState newState = SyncNetwork::NetworkOffline;
bool isOnline = activeConfigs.size() > 0;
if (isOnline) {
// Check if the connection is wifi or ethernet
QNetworkConfiguration defaultConfig = m_configManager->defaultConfiguration();
if (defaultConfig.isValid()) {
if ((defaultConfig.bearerType() == QNetworkConfiguration::BearerWLAN) ||
(defaultConfig.bearerType() == QNetworkConfiguration::BearerEthernet)) {
newState = SyncNetwork::NetworkOnline;
} else {
// if the connection is not wifi or ethernet it will consider it as offline
newState = SyncNetwork::NetworkPartialOnline;
}
}
qDebug() << "New connection type:" << defaultConfig.bearerTypeName();
} else {
qDebug() << "Network is offline";
}
setState(newState);
}
sync-monitor-0.2+16.04.20160304/src/sync-queue.h 0000644 0000156 0000165 00000003617 12666332064 021431 0 ustar pbuser pbgroup 0000000 0000000 /*
* Copyright 2014 Canonical Ltd.
*
* This file is part of sync-monitor.
*
* sync-monitor 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; version 3.
*
* contact-service-app 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 .
*/
#ifndef __SYNC_QUEUE_H__
#define __SYNC_QUEUE_H__
#include
#include
#include
class SyncAccount;
class SyncJob
{
public:
SyncJob();
SyncJob(SyncAccount *account, const QString &serviceName, bool runOnPayedConnection);
SyncAccount *account() const;
QString serviceName() const;
bool runOnPayedConnection() const;
bool operator==(const SyncJob &other) const;
bool isValid() const;
private:
SyncAccount *m_account;
QString m_serviceName;
bool m_runOnPayedConnection;
};
class SyncQueue
{
public:
SyncJob popNext();
void push(const SyncQueue &other);
void push(const SyncJob &job);
void push(SyncAccount *account, const QString &serviceName, bool syncOnPayedConnection);
void push(SyncAccount *account, const QStringList &serviceNames = QStringList(), bool syncOnPayedConnection = false);
bool contains(const SyncJob &otherJob) const;
bool contains(SyncAccount *account, const QString &serviceName) const;
void remove(SyncAccount *account, const QString &serviceName = QString());
int count() const;
bool isEmpty() const;
void clear();
QList jobs() const;
private:
QList m_jobs;
};
#endif
sync-monitor-0.2+16.04.20160304/src/syncevolution-session-proxy.h 0000644 0000156 0000165 00000003511 12666332064 025105 0 ustar pbuser pbgroup 0000000 0000000 #ifndef __SYNCEVOLUTION_SESSION_PROXY_H__
/*
* Copyright 2014 Canonical Ltd.
*
* This file is part of sync-monitor.
*
* sync-monitor 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; version 3.
*
* contact-service-app 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 .
*/
#define __SYNCEVOLUTION_SESSION_PROXY_H__
#include "dbustypes.h"
#include
#include
#include
#include
class SyncEvolutionSessionProxy : public QObject
{
Q_OBJECT
public:
QString id() const;
void destroy();
QString status() const;
bool hasConfig(const QString &configName);
QStringMultiMap getConfig(const QString &configName, bool isTemplate);
bool saveConfig(const QString &configName, QStringMultiMap config);
void detach();
bool isValid() const;
void sync(QStringMap services);
QArrayOfStringMap reports(uint start, uint maxCount);
Q_SIGNALS:
void statusChanged(const QString &status);
void progressChanged(int progress);
void error(uint error);
private Q_SLOTS:
void onSessionStatusChanged(const QString &status, uint error, QSyncStatusMap source);
void onSessionProgressChanged(int progress, QSyncProgressMap sources);
private:
QDBusInterface *m_iface;
SyncEvolutionSessionProxy(const QDBusObjectPath &objectPath, QObject *parent=0);
friend class SyncEvolutionServerProxy;
};
#endif
sync-monitor-0.2+16.04.20160304/src/sync-account.cpp 0000644 0000156 0000165 00000042140 12666332064 022266 0 ustar pbuser pbgroup 0000000 0000000 /*
* Copyright 2014 Canonical Ltd.
*
* This file is part of sync-monitor.
*
* sync-monitor 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; version 3.
*
* contact-service-app 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 .
*/
#include "sync-account.h"
#include "sync-configure.h"
#include "syncevolution-server-proxy.h"
#include "syncevolution-session-proxy.h"
#include "sync-i18n.h"
#include "config.h"
using namespace Accounts;
SyncAccount::SyncAccount(Account *account,
QSettings *settings,
QObject *parent)
: QObject(parent),
m_currentSession(0),
m_account(account),
m_state(SyncAccount::Idle),
m_settings(settings),
m_lastError(0),
m_retrySync(true)
{
setup();
}
SyncAccount::SyncAccount(Account *account,
const QString &service,
QSettings *settings,
QObject *parent)
: QObject(parent),
m_currentSession(0),
m_account(account),
m_state(SyncAccount::Idle),
m_settings(settings),
m_lastError(0),
m_retrySync(true)
{
m_availabeServices.insert(service, true);
}
SyncAccount::~SyncAccount()
{
cancel();
}
// Load all available services for the online-account
// fill the m_availabeServices with the service name
// and a flag to say it is enabled or not
void SyncAccount::setupServices()
{
m_availabeServices.clear();
if (m_settings) {
QStringList supportedSevices = m_settings->childGroups();
ServiceList enabledServices = m_account->enabledServices();
Q_FOREACH(Service service, m_account->services()) {
if (supportedSevices.contains(service.serviceType())) {
bool enabled = m_account->enabled() && enabledServices.contains(service);
m_availabeServices.insert(service.serviceType(), enabled);
}
}
qDebug() << "Supported sevices for protocol:" << m_account->providerName() << supportedSevices;
qDebug() << "Services available for:" << m_account->displayName() << m_availabeServices;
}
}
QString SyncAccount::sessionName(const QString &serviceName) const
{
return QString("%1-%2-%3")
.arg(m_account->providerName())
.arg(serviceName)
.arg(m_account->id());
}
QString SyncAccount::sourceName(const QString &serviceName) const
{
return QString("%1_uoa_%2")
.arg(serviceName)
.arg(m_account->id());
}
void SyncAccount::dumpReport(const QStringMap &report) const
{
Q_FOREACH(const QString &key, report.keys()) {
qDebug() << "\t" << key << ":" << report[key];
}
}
void SyncAccount::setup()
{
setupServices();
if (m_account) {
connect(m_account,
SIGNAL(enabledChanged(QString,bool)),
SLOT(onAccountEnabledChanged(QString,bool)));
}
}
void SyncAccount::cancel(const QString &serviceName)
{
//TODO: cancel the only the seviceName sync
if (m_currentSession) {
m_currentSession->destroy();
m_currentSession = 0;
if (m_state == SyncAccount::Syncing) {
Q_EMIT syncError(serviceName, "canceled");
} else {
qDebug() << "Cancelled with no sync state";
}
setState(SyncAccount::Idle);
}
}
void SyncAccount::sync(const QString &serviceName)
{
switch(m_state) {
case SyncAccount::Idle:
qDebug() << "Sync requested service:" << m_account->displayName() << serviceName;
if (prepareSession(serviceName)) {
m_syncMode = syncMode(serviceName, &m_firstSync);
releaseSession();
configure(serviceName, m_syncMode);
} else {
qWarning() << "Fail to connect with syncevolution";
setState(SyncAccount::Idle);
Q_EMIT syncFinished(serviceName, false, "", "");
}
break;
default:
break;
}
}
bool SyncAccount::prepareSession(const QString &serviceName)
{
m_syncServiceName = serviceName;
QString sessionName = this->sessionName(serviceName);
SyncEvolutionServerProxy *proxy = SyncEvolutionServerProxy::instance();
SyncEvolutionSessionProxy *session = proxy->openSession(sessionName,
QStringList());
if (session) {
attachSession(session);
return true;
} else {
return false;
}
}
bool SyncAccount::syncService(const QString &serviceName)
{
bool enabledService = m_availabeServices.value(serviceName, false);
if (!enabledService) {
qDebug() << "Service" << serviceName << "not enabled. Skip sync.";
setState(SyncAccount::Idle);
Q_EMIT syncFinished(serviceName, false, "", "");
return true;
}
if (prepareSession(serviceName)) {
Q_ASSERT(m_currentSession);
QStringMap syncFlags;
syncFlags.insert(sourceName(serviceName), m_syncMode);
m_currentSession->sync(syncFlags);
return true;
} else {
setState(SyncAccount::Invalid);
return false;
}
}
void SyncAccount::continueSync(const QString &serviceName)
{
QStringList services;
if (serviceName.isEmpty()) {
services = m_settings->childGroups();
} else {
services << serviceName;
}
Q_FOREACH(const QString &service, services) {
syncService(service);
}
}
void SyncAccount::wait()
{
//TODO
}
SyncAccount::AccountState SyncAccount::state() const
{
return m_state;
}
QStringMap SyncAccount::lastReport(const QString &serviceName) const
{
const uint pageSize = 100;
uint index = 0;
if (!m_currentSession) {
qDebug() << "Session cancelled";
return QStringMap();
}
QArrayOfStringMap reports = m_currentSession->reports(index, pageSize);
if (reports.isEmpty()) {
return QStringMap();
} else if (serviceName.isEmpty()) {
return reports.value(0);
}
QString sessionName = this->sessionName(serviceName);
index += pageSize;
while (reports.size() != pageSize) {
Q_FOREACH(const QStringMap &report, reports) {
if (report.value("peer") == sessionName) {
return report;
}
}
reports = m_currentSession->reports(index, pageSize);
index += pageSize;
}
Q_FOREACH(const QStringMap &report, reports) {
if (report.value("peer") == sessionName) {
return report;
}
}
return QStringMap();
}
QString SyncAccount::syncMode(const QString &serviceName, bool *firstSync) const
{
QString lastSyncMode = "two-way";
QString lastStatus = lastSyncStatus(serviceName, &lastSyncMode);
*firstSync = lastStatus.isEmpty();
if (*firstSync) {
return "slow";
}
switch(lastStatus.toInt())
{
case 22000:
// "Fail to run \"two-way\" sync";
return "slow";
case 0:
case 200:
case 204:
case 207:
// status ok
return "two-way";
case 401:
case 403:
// "Forbidden / access denied";
case 404:
// "Object not found / unassigned field";
case 405:
// "Command not allowed";
case 406:
case 407:
// "Proxy authentication required";
case 420:
// "Disk full";
case 506:
// "Fail to sync due some remote problem";
case 22001:
// "Fail to sync some items";
case 22002:
// "Last process unexpected die.";
case 20006:
case 20007:
// "Server sent bad content";
case 20020:
// "Connection timeout";
case 20021:
// "Connection certificate has expired";
case 20022:
// "Connection certificate is invalid";
case 20026:
case 20027:
case 20028:
// "Fail to connect with the server";
case 20046:
case 20047:
// "Server not found";
default:
return lastSyncMode;
}
}
QString SyncAccount::lastSyncStatus(const QString &serviceName, QString *lastSyncMode) const
{
QString sourceName = this->sourceName(serviceName).replace("_", "__");
QStringMap lastReport = this->lastReport(serviceName);
QString lastStatus;
if (!lastReport.isEmpty()) {
lastStatus = lastReport.value("status", "");
*lastSyncMode = lastReport.value(QString("source-%1-mode").arg(sourceName), "slow");
} else {
QString statusMessage = statusDescription(lastStatus);
qDebug() << QString("Last report start date: %1, Status: %2 Message: %3")
.arg(QDateTime::fromTime_t(lastReport.value("start", "0").toUInt()).toString(Qt::SystemLocaleShortDate))
.arg(lastStatus)
.arg(statusMessage.isEmpty() ? "OK" : statusMessage);
}
return lastStatus;
}
bool SyncAccount::enabled() const
{
return m_account->enabled();
}
QString SyncAccount::displayName() const
{
return m_account->displayName();
}
int SyncAccount::id() const
{
return m_account->id();
}
QString SyncAccount::iconName(const QString &serviceName) const
{
QString iconName;
Q_FOREACH(const Service &service, m_account->services()) {
if (service.serviceType() == serviceName) {
iconName = service.iconName();
break;
}
}
// use icon name based on the current theme intead of hardcoded name
if (iconName.isEmpty()) {
return QString("/usr/share/icons/ubuntu-mobile/actions/scalable/reload.svg");
} else {
return QString("/usr/share/icons/ubuntu-mobile/apps/scalable/%1.svg").arg(iconName);
}
}
QStringList SyncAccount::availableServices() const
{
return m_availabeServices.keys();
}
QStringList SyncAccount::enabledServices() const
{
QStringList result;
Q_FOREACH(const Service &service, m_account->enabledServices()) {
result << service.serviceType();
}
return result;
}
uint SyncAccount::lastError() const
{
return m_lastError;
}
void SyncAccount::setLastError(uint errorCode)
{
m_lastError = errorCode;
}
QString SyncAccount::serviceId(const QString &serviceName) const
{
Q_FOREACH(Service service, m_account->services()) {
qDebug() << service.serviceType() << service.name();
if (service.serviceType() == serviceName) {
return service.name();
}
}
return QString();
}
bool SyncAccount::retrySync() const
{
return m_retrySync;
}
void SyncAccount::setRetrySync(bool retry)
{
m_retrySync = retry;
}
void SyncAccount::onAccountEnabledChanged(const QString &serviceName, bool enabled)
{
// empty service name means that the hole account has been enabled/disabled
if (serviceName.isEmpty()) {
setupServices();
Q_EMIT enableChanged(QString(), enabled);
} else {
// get service type
QString serviceType = serviceName;
Q_FOREACH(Service service, m_account->services()) {
if (service.name() == serviceName) {
serviceType = service.serviceType();
break;
}
}
if (m_availabeServices.contains(serviceType)) {
m_availabeServices[serviceType] = enabled;
Q_EMIT enableChanged(serviceType, enabled);
}
}
}
void SyncAccount::onSessionStatusChanged(const QString &newStatus)
{
if (newStatus == "running") {
switch (m_state) {
case SyncAccount::Idle:
setState(SyncAccount::Syncing);
Q_EMIT syncStarted(m_syncServiceName, m_firstSync);
break;
case SyncAccount::Syncing:
break;
default:
qWarning() << "State changed to" << newStatus << "during" << state();
break;
}
} else if (newStatus == "done") {
QString lastSyncMode;
QString lastStatus = lastSyncStatus(m_syncServiceName, &lastSyncMode);
QStringMap lastReport = this->lastReport(m_syncServiceName);
qDebug() << "Sync Report";
dumpReport(lastReport);
releaseSession();
switch (m_state) {
case SyncAccount::Syncing:
{
QString currentServiceName = m_syncServiceName;
bool firstSync = m_firstSync;
QString currentSyncMode = m_syncMode;
m_syncMode.clear();
m_syncServiceName.clear();
m_firstSync = false;
setState(SyncAccount::Idle);
Q_EMIT syncFinished(currentServiceName, firstSync, lastStatus, currentSyncMode);
break;
}
default:
qWarning() << "State changed to" << newStatus << "during" << state();
break;
}
} else if (newStatus == "running;waiting") {
// ignore
} else {
qWarning() << "Status changed invalid;" << newStatus;
}
}
void SyncAccount::onSessionProgressChanged(int progress)
{
qDebug() << "Progress" << progress;
}
void SyncAccount::onSessionError(uint error)
{
qWarning() << "Session error" << error;
setState(SyncAccount::Idle);
}
// configure syncevolution with the necessary information for sync
void SyncAccount::configure(const QString &serviceName, const QString &syncMode)
{
qDebug() << "Configure account for service:"
<< m_account->displayName() << serviceName << syncMode;
setState(SyncAccount::Configuring);
SyncConfigure *configure = new SyncConfigure(m_account, m_settings, this);
m_pendingConfigs << configure;
connect(configure, &SyncConfigure::done,
this, &SyncAccount::onAccountConfigured);
connect(configure, &SyncConfigure::error,
this, &SyncAccount::onAccountConfigureError);
configure->configure(serviceName, syncMode);
}
void SyncAccount::onAccountConfigured()
{
SyncConfigure *configure = qobject_cast(QObject::sender());
m_pendingConfigs.removeOne(configure);
QString serviceName = configure->serviceName();
configure->deleteLater();
Q_EMIT configured(serviceName);
setState(SyncAccount::Idle);
continueSync(serviceName);
}
void SyncAccount::onAccountConfigureError()
{
SyncConfigure *configure = qobject_cast(QObject::sender());
m_pendingConfigs.removeOne(configure);
configure->deleteLater();
// TODO: notify error
setState(SyncAccount::Invalid);
qWarning() << "Fail to configure account" << m_account->id() << m_account->displayName();
}
void SyncAccount::setState(SyncAccount::AccountState state)
{
if (m_state != state) {
m_state = state;
Q_EMIT stateChanged(m_state);
}
}
void SyncAccount::attachSession(SyncEvolutionSessionProxy *session)
{
Q_ASSERT(m_currentSession == 0);
m_currentSession = session;
m_sessionConnections << connect(m_currentSession,
SIGNAL(statusChanged(QString)),
SLOT(onSessionStatusChanged(QString)));
m_sessionConnections << connect(m_currentSession,
SIGNAL(progressChanged(int)),
SLOT(onSessionProgressChanged(int)));
m_sessionConnections << connect(m_currentSession,
SIGNAL(error(uint)),
SLOT(onSessionError(uint)));
}
void SyncAccount::releaseSession()
{
if (m_currentSession) {
Q_FOREACH(QMetaObject::Connection conn, m_sessionConnections) {
disconnect(conn);
}
m_sessionConnections.clear();
m_currentSession->destroy();
m_currentSession->deleteLater();
m_currentSession = 0;
}
}
QString SyncAccount::statusDescription(const QString &status)
{
if (status.isEmpty()) {
return "";
}
switch(status.toInt())
{
case 0:
case 200:
case 204:
case 207:
// OK
return "";
case 401:
case 403:
return _("Forbidden / access denied");
case 404:
return _("Object not found / unassigned field");
case 405:
return _("Command not allowed");
case 406:
case 407:
return _("Proxy authentication required");
case 420:
return _("Disk full");
case 506:
return _("Fail to sync due some remote problem");
case 22000:
return _("Fail to run \"two-way\" sync");
case 22001:
return _("Fail to sync some items");
case 22002:
return _("Process unexpected die.");
case 20006:
case 20007:
return _("Server sent bad content");
case 20017:
return _("Sync canceled");
case 20020:
return _("Connection timeout");
case 20021:
return _("Connection certificate has expired");
case 20022:
return _("Connection certificate is invalid");
case 20026:
case 20027:
case 20028:
return _("Fail to connect with the server");
case 20046:
case 20047:
return _( "Server not found");
default:
return _("Unknown status");
}
}
sync-monitor-0.2+16.04.20160304/src/syncevolution-session-proxy.cpp 0000644 0000156 0000165 00000012772 12666332064 025451 0 ustar pbuser pbgroup 0000000 0000000 /*
* Copyright 2014 Canonical Ltd.
*
* This file is part of sync-monitor.
*
* sync-monitor 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; version 3.
*
* contact-service-app 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 .
*/
#include "syncevolution-session-proxy.h"
#include "dbustypes.h"
#include
#include
#define SYNCEVOLUTION_SERVICE_NAME "org.syncevolution"
#define SYNCEVOLUTIOON_SESSION_IFACE_NAME "org.syncevolution.Session"
SyncEvolutionSessionProxy::SyncEvolutionSessionProxy(const QDBusObjectPath &objectPath, QObject *parent)
: QObject(parent)
{
m_iface = new QDBusInterface(SYNCEVOLUTION_SERVICE_NAME,
objectPath.path(),
SYNCEVOLUTIOON_SESSION_IFACE_NAME);
m_iface->connection().connect(SYNCEVOLUTION_SERVICE_NAME,
objectPath.path(),
SYNCEVOLUTIOON_SESSION_IFACE_NAME,
"StatusChanged",
this,
SLOT(onSessionStatusChanged(QString,uint, QSyncStatusMap)));
m_iface->connection().connect(SYNCEVOLUTION_SERVICE_NAME,
objectPath.path(),
SYNCEVOLUTIOON_SESSION_IFACE_NAME,
"ProgressChanged",
this,
SLOT(onSessionProgressChanged(int, QSyncProgressMap)));
}
QString SyncEvolutionSessionProxy::id() const
{
Q_ASSERT(isValid());
return m_iface->path();
}
void SyncEvolutionSessionProxy::destroy()
{
// abort any operation
m_iface->call("Abort");
// notify server to close the session
m_iface->call("Detach");
// delete interface
m_iface->deleteLater();
m_iface = 0;
}
QString SyncEvolutionSessionProxy::status() const
{
Q_ASSERT(isValid());
QDBusReply reply = m_iface->call("GetStatus");
if (reply.error().isValid()) {
qWarning() << "Fail to get session status" << reply.error().message();
return QString();
} else {
return reply.value();
}
}
bool SyncEvolutionSessionProxy::hasConfig(const QString &configName)
{
Q_ASSERT(isValid());
QDBusReply reply = m_iface->call("GetNamedConfig", configName, false);
if (reply.error().isValid()) {
qWarning() << "Fail to get session named config" << reply.error().message();
return false;
}
return (reply.value().size() > 0);
}
QStringMultiMap SyncEvolutionSessionProxy::getConfig(const QString &configName,
bool isTemplate)
{
Q_ASSERT(isValid());
QDBusReply reply = m_iface->call("GetNamedConfig",
configName,
isTemplate);
if (reply.error().isValid()) {
qWarning() << "Fail to get session named config" << reply.error().message();
return QStringMultiMap();
}
return reply.value();
}
bool SyncEvolutionSessionProxy::saveConfig(const QString &configName,
QStringMultiMap config)
{
Q_ASSERT(isValid());
QDBusReply reply;
if (configName.isEmpty()) {
reply = m_iface->call("SetConfig",
false,
false,
QVariant::fromValue(config));
} else {
reply = m_iface->call("SetNamedConfig",
configName,
false,
false,
QVariant::fromValue(config));
}
if (reply.error().isValid()) {
qWarning() << "Fail to save named config" << reply.error().message();
return false;
}
return true;
}
bool SyncEvolutionSessionProxy::isValid() const
{
return (m_iface != 0);
}
void SyncEvolutionSessionProxy::sync(QStringMap services)
{
Q_ASSERT(isValid());
QDBusReply reply = m_iface->call("Sync", QString(), QVariant::fromValue(services));
if (reply.error().isValid()) {
qWarning() << "Fail to sync account" << reply.error().message();
Q_EMIT this->error(0);
}
}
QArrayOfStringMap SyncEvolutionSessionProxy::reports(uint start, uint maxCount)
{
QDBusReply reply = m_iface->call("GetReports", start, maxCount);
if (reply.error().isValid()) {
qWarning() << "Fail to get sync reports" << reply.error().message();
return QArrayOfStringMap();
} else {
return reply.value();
}
}
void SyncEvolutionSessionProxy::onSessionStatusChanged(const QString &status, uint errorNuber, QSyncStatusMap source)
{
Q_UNUSED(source);
Q_EMIT statusChanged(status);
if (errorNuber != 0) {
Q_EMIT error(errorNuber);
}
}
void SyncEvolutionSessionProxy::onSessionProgressChanged(int progress, QSyncProgressMap sources)
{
Q_UNUSED(sources);
Q_EMIT progressChanged(progress);
}
sync-monitor-0.2+16.04.20160304/src/CMakeLists.txt 0000644 0000156 0000165 00000002520 12666332064 021712 0 ustar pbuser pbgroup 0000000 0000000 project(synq-src)
set(SYNQ_BIN sync-monitor)
set(SYNQ_LIB synq-lib)
set(SYNQ_LIB_SRC
eds-helper.h
eds-helper.cpp
notify-message.h
notify-message.cpp
provider-template.h
provider-template.cpp
sync-account.h
sync-account.cpp
sync-configure.h
sync-configure.cpp
sync-daemon.h
sync-daemon.cpp
sync-dbus.h
sync-dbus.cpp
sync-i18n.h
sync-queue.h
sync-queue.cpp
sync-network.h
sync-network.cpp
syncevolution-server-proxy.h
syncevolution-server-proxy.cpp
syncevolution-session-proxy.h
syncevolution-session-proxy.cpp
)
add_library(${SYNQ_LIB} STATIC
${SYNQ_LIB_SRC}
)
target_link_libraries(${SYNQ_LIB}
${ACCOUNTS_LIBRARIES}
${LIBNOTIFY_LIBRARIES}
${URLDISPATCHER_LIBRARIES}
syncevolution-qt
)
qt5_use_modules(${SYNQ_LIB} Core DBus Organizer Contacts Network)
set(SYNQ_BIN_SRC
main.cpp
)
add_executable(${SYNQ_BIN}
${SYNQ_BIN_SRC}
)
target_link_libraries(${SYNQ_BIN}
${SYNQ_LIB}
)
qt5_use_modules(${SYNQ_BIN} Core )
include_directories(
${CMAKE_SOURCE_DIR}
${CMAKE_BINARY_DIR}
${ACCOUNTS_INCLUDE_DIRS}
${LIBNOTIFY_INCLUDE_DIRS}
${URLDISPATCHER_INCLUDE_DIRS}
${syncevolution-qt_SOURCE_DIR}
)
install(TARGETS ${SYNQ_BIN}
RUNTIME DESTINATION ${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}/sync-monitor/)
sync-monitor-0.2+16.04.20160304/src/sync-queue.cpp 0000644 0000156 0000165 00000007007 12666332064 021761 0 ustar pbuser pbgroup 0000000 0000000 /*
* Copyright 2014 Canonical Ltd.
*
* This file is part of sync-monitor.
*
* sync-monitor 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; version 3.
*
* contact-service-app 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 .
*/
#include "sync-queue.h"
#include "sync-account.h"
int SyncQueue::count() const
{
return m_jobs.count();
}
bool SyncQueue::isEmpty() const
{
return m_jobs.isEmpty();
}
void SyncQueue::clear()
{
m_jobs.clear();;
}
QList SyncQueue::jobs() const
{
return m_jobs;
}
void SyncQueue::push(SyncAccount *account,
const QStringList &serviceNames,
bool syncOnPayedConnection)
{
QStringList newServices;
if (serviceNames.isEmpty()) {
newServices = account->availableServices();
} else {
newServices = serviceNames;
}
Q_FOREACH(const QString &serviceName, newServices) {
SyncJob job(account, serviceName, syncOnPayedConnection);
push(job);
}
}
void SyncQueue::push(SyncAccount *account,
const QString &serviceName,
bool syncOnPayedConnection)
{
QStringList services;
if (!serviceName.isEmpty()) {
services << serviceName;
}
push(account, services, syncOnPayedConnection);
}
void SyncQueue::push(const SyncQueue &other)
{
Q_FOREACH(const SyncJob &job, other.jobs()) {
push(job);
}
}
void SyncQueue::push(const SyncJob &job)
{
if (!contains(job)) {
m_jobs << job;
}
}
bool SyncQueue::contains(const SyncJob &otherJob) const
{
return contains(otherJob.account(), otherJob.serviceName());
}
bool SyncQueue::contains(SyncAccount *account, const QString &serviceName) const
{
Q_FOREACH(const SyncJob &job, m_jobs) {
if ((job.account() == account) &&
(serviceName.isEmpty() || (job.serviceName() == serviceName))) {
return true;
}
}
return false;
}
SyncJob SyncQueue::popNext()
{
if (m_jobs.isEmpty()) {
return SyncJob();
}
return m_jobs.takeFirst();
}
void SyncQueue::remove(SyncAccount *account, const QString &serviceName)
{
QList newList = m_jobs;
for(int i=0; i < m_jobs.count(); i++) {
const SyncJob &job = m_jobs[i];
if ((job.account() == account) &&
(serviceName.isEmpty() || (job.serviceName() == serviceName))) {
newList.removeOne(job);
}
}
m_jobs = newList;
}
SyncJob::SyncJob()
{
}
SyncJob::SyncJob(SyncAccount *account, const QString &serviceName, bool runOnPayedConnection)
: m_account(account), m_serviceName(serviceName), m_runOnPayedConnection(runOnPayedConnection)
{
}
SyncAccount *SyncJob::account() const
{
return m_account;
}
QString SyncJob::serviceName() const
{
return m_serviceName;
}
bool SyncJob::runOnPayedConnection() const
{
return m_runOnPayedConnection;
}
bool SyncJob::operator==(const SyncJob &other) const
{
return (m_account == other.account()) && (m_serviceName == other.serviceName());
}
bool SyncJob::isValid() const
{
return ((m_account != 0) && !m_serviceName.isEmpty());
}
sync-monitor-0.2+16.04.20160304/src/sync-configure.h 0000644 0000156 0000165 00000004064 12666332064 022263 0 ustar pbuser pbgroup 0000000 0000000 /*
* Copyright 2014 Canonical Ltd.
*
* This file is part of sync-monitor.
*
* sync-monitor 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; version 3.
*
* contact-service-app 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 .
*/
#ifndef __SYNC_CONFIGURE_H__
#define __SYNC_CONFIGURE_H__
#include
#include
#include
class SyncEvolutionSessionProxy;
class SyncConfigure : public QObject
{
Q_OBJECT
public:
SyncConfigure(Accounts::Account *account,
QSettings *settings,
QObject *parent = 0);
~SyncConfigure();
void configure(const QString &serviceName, const QString &syncMode);
void configureAll(const QString &syncMode);
QString serviceName() const;
Q_SIGNALS:
void done();
void error();
public Q_SLOTS:
void onSessionStatusChanged(const QString &newStatus);
void onSessionError(uint error);
private:
Accounts::Account *m_account;
QMap m_sessions;
QSettings *m_settings;
QStringList m_services;
QString m_originalServiceName;
QString m_syncMode;
void continueConfigure();
void configureServices(const QString &syncMode);
void configureService(const QString &serviceName, const QString &syncMode);
void removeService(const QString &serviceName);
bool configTarget(const QString &targetName, const QString &serviceName);
bool configSync(const QString &targetName, const QString &serviceName, const QString &syncMode);
bool changeSyncMode(const QString &targetName, const QString &serviceName, const QString &syncMode);
};
#endif
sync-monitor-0.2+16.04.20160304/src/provider-template.cpp 0000644 0000156 0000165 00000004405 12666332064 023325 0 ustar pbuser pbgroup 0000000 0000000 /*
* Copyright 2014 Canonical Ltd.
*
* This file is part of sync-monitor.
*
* sync-monitor 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; version 3.
*
* contact-service-app 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 .
*/
#include "provider-template.h"
#include
#include
#include "config.h"
ProviderTemplate::ProviderTemplate()
{
m_baseDir = qgetenv("SYNC_MONITOR_TEMPLATE_PATH");
if (m_baseDir.isEmpty()) {
m_baseDir = QString(PROVIDER_TEMPLATE_PATH);
} else {
qDebug() << "loading templates from a alternative path: " << m_baseDir;
}
}
ProviderTemplate::~ProviderTemplate()
{
qDeleteAll(m_providers.values());
m_providers.clear();
}
void ProviderTemplate::load()
{
if (!m_providers.isEmpty()) {
qWarning() << "ProviderTemplate already loaded";
return;
}
QDir templateDir(PROVIDER_TEMPLATE_PATH);
if (templateDir.exists()) {
Q_FOREACH(QString templateFile, templateDir.entryList(QStringList() << "*.conf")) {
QSettings *settings = new QSettings(templateDir.absoluteFilePath(templateFile), QSettings::IniFormat);
QString providerName = templateFile.replace(".conf", "");
m_providers.insert(providerName, settings);
}
} else {
qWarning() << "Template directory does not exists.";
}
qDebug() << "Loaded tempaltes:" << m_providers.keys();
}
bool ProviderTemplate::contains(const QString &provider) const
{
return m_providers.contains(provider);
}
QStringList ProviderTemplate::supportedServices(const QString &provider) const
{
if (m_providers.contains(provider)) {
return m_providers[provider]->childGroups();
}
return QStringList();
}
QSettings *ProviderTemplate::settings(const QString &provider) const
{
return m_providers.value(provider, 0);
}
sync-monitor-0.2+16.04.20160304/LICENSE.LGPL 0000644 0000156 0000165 00000064107 12666332064 020136 0 ustar pbuser pbgroup 0000000 0000000 GNU LESSER GENERAL PUBLIC LICENSE
You may use, distribute and copy the sync-monitor under the terms of
GNU Lesser General Public License version 2.1, which is displayed below.
-------------------------------------------------------------------------
GNU LESSER GENERAL PUBLIC LICENSE
Version 2.1, February 1999
Copyright (C) 1991, 1999 Free Software Foundation, Inc.
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
[This is the first released version of the Lesser GPL. It also counts
as the successor of the GNU Library Public License, version 2, hence
the version number 2.1.]
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
Licenses are intended to guarantee your freedom to share and change
free software--to make sure the software is free for all its users.
This license, the Lesser General Public License, applies to some
specially designated software packages--typically libraries--of the
Free Software Foundation and other authors who decide to use it. You
can use it too, but we suggest you first think carefully about whether
this license or the ordinary General Public License is the better
strategy to use in any particular case, based on the explanations below.
When we speak of free software, we are referring to freedom of use,
not price. Our General Public Licenses are designed to make sure that
you have the freedom to distribute copies of free software (and charge
for this service if you wish); that you receive source code or can get
it if you want it; that you can change the software and use pieces of
it in new free programs; and that you are informed that you can do
these things.
To protect your rights, we need to make restrictions that forbid
distributors to deny you these rights or to ask you to surrender these
rights. These restrictions translate to certain responsibilities for
you if you distribute copies of the library or if you modify it.
For example, if you distribute copies of the library, whether gratis
or for a fee, you must give the recipients all the rights that we gave
you. You must make sure that they, too, receive or can get the source
code. If you link other code with the library, you must provide
complete object files to the recipients, so that they can relink them
with the library after making changes to the library and recompiling
it. And you must show them these terms so they know their rights.
We protect your rights with a two-step method: (1) we copyright the
library, and (2) we offer you this license, which gives you legal
permission to copy, distribute and/or modify the library.
To protect each distributor, we want to make it very clear that
there is no warranty for the free library. Also, if the library is
modified by someone else and passed on, the recipients should know
that what they have is not the original version, so that the original
author's reputation will not be affected by problems that might be
introduced by others.
Finally, software patents pose a constant threat to the existence of
any free program. We wish to make sure that a company cannot
effectively restrict the users of a free program by obtaining a
restrictive license from a patent holder. Therefore, we insist that
any patent license obtained for a version of the library must be
consistent with the full freedom of use specified in this license.
Most GNU software, including some libraries, is covered by the
ordinary GNU General Public License. This license, the GNU Lesser
General Public License, applies to certain designated libraries, and
is quite different from the ordinary General Public License. We use
this license for certain libraries in order to permit linking those
libraries into non-free programs.
When a program is linked with a library, whether statically or using
a shared library, the combination of the two is legally speaking a
combined work, a derivative of the original library. The ordinary
General Public License therefore permits such linking only if the
entire combination fits its criteria of freedom. The Lesser General
Public License permits more lax criteria for linking other code with
the library.
We call this license the "Lesser" General Public License because it
does Less to protect the user's freedom than the ordinary General
Public License. It also provides other free software developers Less
of an advantage over competing non-free programs. These disadvantages
are the reason we use the ordinary General Public License for many
libraries. However, the Lesser license provides advantages in certain
special circumstances.
For example, on rare occasions, there may be a special need to
encourage the widest possible use of a certain library, so that it becomes
a de-facto standard. To achieve this, non-free programs must be
allowed to use the library. A more frequent case is that a free
library does the same job as widely used non-free libraries. In this
case, there is little to gain by limiting the free library to free
software only, so we use the Lesser General Public License.
In other cases, permission to use a particular library in non-free
programs enables a greater number of people to use a large body of
free software. For example, permission to use the GNU C Library in
non-free programs enables many more people to use the whole GNU
operating system, as well as its variant, the GNU/Linux operating
system.
Although the Lesser General Public License is Less protective of the
users' freedom, it does ensure that the user of a program that is
linked with the Library has the freedom and the wherewithal to run
that program using a modified version of the Library.
The precise terms and conditions for copying, distribution and
modification follow. Pay close attention to the difference between a
"work based on the library" and a "work that uses the library". The
former contains code derived from the library, whereas the latter must
be combined with the library in order to run.
GNU LESSER GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License Agreement applies to any software library or other
program which contains a notice placed by the copyright holder or
other authorized party saying it may be distributed under the terms of
this Lesser General Public License (also called "this License").
Each licensee is addressed as "you".
A "library" means a collection of software functions and/or data
prepared so as to be conveniently linked with application programs
(which use some of those functions and data) to form executables.
The "Library", below, refers to any such software library or work
which has been distributed under these terms. A "work based on the
Library" means either the Library or any derivative work under
copyright law: that is to say, a work containing the Library or a
portion of it, either verbatim or with modifications and/or translated
straightforwardly into another language. (Hereinafter, translation is
included without limitation in the term "modification".)
"Source code" for a work means the preferred form of the work for
making modifications to it. For a library, complete source code means
all the source code for all modules it contains, plus any associated
interface definition files, plus the scripts used to control compilation
and installation of the library.
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running a program using the Library is not restricted, and output from
such a program is covered only if its contents constitute a work based
on the Library (independent of the use of the Library in a tool for
writing it). Whether that is true depends on what the Library does
and what the program that uses the Library does.
1. You may copy and distribute verbatim copies of the Library's
complete source code as you receive it, in any medium, provided that
you conspicuously and appropriately publish on each copy an
appropriate copyright notice and disclaimer of warranty; keep intact
all the notices that refer to this License and to the absence of any
warranty; and distribute a copy of this License along with the
Library.
You may charge a fee for the physical act of transferring a copy,
and you may at your option offer warranty protection in exchange for a
fee.
2. You may modify your copy or copies of the Library or any portion
of it, thus forming a work based on the Library, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
a) The modified work must itself be a software library.
b) You must cause the files modified to carry prominent notices
stating that you changed the files and the date of any change.
c) You must cause the whole of the work to be licensed at no
charge to all third parties under the terms of this License.
d) If a facility in the modified Library refers to a function or a
table of data to be supplied by an application program that uses
the facility, other than as an argument passed when the facility
is invoked, then you must make a good faith effort to ensure that,
in the event an application does not supply such function or
table, the facility still operates, and performs whatever part of
its purpose remains meaningful.
(For example, a function in a library to compute square roots has
a purpose that is entirely well-defined independent of the
application. Therefore, Subsection 2d requires that any
application-supplied function or table used by this function must
be optional: if the application does not supply it, the square
root function must still compute square roots.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Library,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Library, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote
it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Library.
In addition, mere aggregation of another work not based on the Library
with the Library (or with a work based on the Library) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may opt to apply the terms of the ordinary GNU General Public
License instead of this License to a given copy of the Library. To do
this, you must alter all the notices that refer to this License, so
that they refer to the ordinary GNU General Public License, version 2,
instead of to this License. (If a newer version than version 2 of the
ordinary GNU General Public License has appeared, then you can specify
that version instead if you wish.) Do not make any other change in
these notices.
Once this change is made in a given copy, it is irreversible for
that copy, so the ordinary GNU General Public License applies to all
subsequent copies and derivative works made from that copy.
This option is useful when you wish to copy part of the code of
the Library into a program that is not a library.
4. You may copy and distribute the Library (or a portion or
derivative of it, under Section 2) in object code or executable form
under the terms of Sections 1 and 2 above provided that you accompany
it with the complete corresponding machine-readable source code, which
must be distributed under the terms of Sections 1 and 2 above on a
medium customarily used for software interchange.
If distribution of object code is made by offering access to copy
from a designated place, then offering equivalent access to copy the
source code from the same place satisfies the requirement to
distribute the source code, even though third parties are not
compelled to copy the source along with the object code.
5. A program that contains no derivative of any portion of the
Library, but is designed to work with the Library by being compiled or
linked with it, is called a "work that uses the Library". Such a
work, in isolation, is not a derivative work of the Library, and
therefore falls outside the scope of this License.
However, linking a "work that uses the Library" with the Library
creates an executable that is a derivative of the Library (because it
contains portions of the Library), rather than a "work that uses the
library". The executable is therefore covered by this License.
Section 6 states terms for distribution of such executables.
When a "work that uses the Library" uses material from a header file
that is part of the Library, the object code for the work may be a
derivative work of the Library even though the source code is not.
Whether this is true is especially significant if the work can be
linked without the Library, or if the work is itself a library. The
threshold for this to be true is not precisely defined by law.
If such an object file uses only numerical parameters, data
structure layouts and accessors, and small macros and small inline
functions (ten lines or less in length), then the use of the object
file is unrestricted, regardless of whether it is legally a derivative
work. (Executables containing this object code plus portions of the
Library will still fall under Section 6.)
Otherwise, if the work is a derivative of the Library, you may
distribute the object code for the work under the terms of Section 6.
Any executables containing that work also fall under Section 6,
whether or not they are linked directly with the Library itself.
6. As an exception to the Sections above, you may also combine or
link a "work that uses the Library" with the Library to produce a
work containing portions of the Library, and distribute that work
under terms of your choice, provided that the terms permit
modification of the work for the customer's own use and reverse
engineering for debugging such modifications.
You must give prominent notice with each copy of the work that the
Library is used in it and that the Library and its use are covered by
this License. You must supply a copy of this License. If the work
during execution displays copyright notices, you must include the
copyright notice for the Library among them, as well as a reference
directing the user to the copy of this License. Also, you must do one
of these things:
a) Accompany the work with the complete corresponding
machine-readable source code for the Library including whatever
changes were used in the work (which must be distributed under
Sections 1 and 2 above); and, if the work is an executable linked
with the Library, with the complete machine-readable "work that
uses the Library", as object code and/or source code, so that the
user can modify the Library and then relink to produce a modified
executable containing the modified Library. (It is understood
that the user who changes the contents of definitions files in the
Library will not necessarily be able to recompile the application
to use the modified definitions.)
b) Use a suitable shared library mechanism for linking with the
Library. A suitable mechanism is one that (1) uses at run time a
copy of the library already present on the user's computer system,
rather than copying library functions into the executable, and (2)
will operate properly with a modified version of the library, if
the user installs one, as long as the modified version is
interface-compatible with the version that the work was made with.
c) Accompany the work with a written offer, valid for at
least three years, to give the same user the materials
specified in Subsection 6a, above, for a charge no more
than the cost of performing this distribution.
d) If distribution of the work is made by offering access to copy
from a designated place, offer equivalent access to copy the above
specified materials from the same place.
e) Verify that the user has already received a copy of these
materials or that you have already sent this user a copy.
For an executable, the required form of the "work that uses the
Library" must include any data and utility programs needed for
reproducing the executable from it. However, as a special exception,
the materials to be distributed need not include anything that is
normally distributed (in either source or binary form) with the major
components (compiler, kernel, and so on) of the operating system on
which the executable runs, unless that component itself accompanies
the executable.
It may happen that this requirement contradicts the license
restrictions of other proprietary libraries that do not normally
accompany the operating system. Such a contradiction means you cannot
use both them and the Library together in an executable that you
distribute.
7. You may place library facilities that are a work based on the
Library side-by-side in a single library together with other library
facilities not covered by this License, and distribute such a combined
library, provided that the separate distribution of the work based on
the Library and of the other library facilities is otherwise
permitted, and provided that you do these two things:
a) Accompany the combined library with a copy of the same work
based on the Library, uncombined with any other library
facilities. This must be distributed under the terms of the
Sections above.
b) Give prominent notice with the combined library of the fact
that part of it is a work based on the Library, and explaining
where to find the accompanying uncombined form of the same work.
8. You may not copy, modify, sublicense, link with, or distribute
the Library except as expressly provided under this License. Any
attempt otherwise to copy, modify, sublicense, link with, or
distribute the Library is void, and will automatically terminate your
rights under this License. However, parties who have received copies,
or rights, from you under this License will not have their licenses
terminated so long as such parties remain in full compliance.
9. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Library or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Library (or any work based on the
Library), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Library or works based on it.
10. Each time you redistribute the Library (or any work based on the
Library), the recipient automatically receives a license from the
original licensor to copy, distribute, link with or modify the Library
subject to these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties with
this License.
11. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Library at all. For example, if a patent
license would not permit royalty-free redistribution of the Library by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Library.
If any portion of this section is held invalid or unenforceable under any
particular circumstance, the balance of the section is intended to apply,
and the section as a whole is intended to apply in other circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
12. If the distribution and/or use of the Library is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Library under this License may add
an explicit geographical distribution limitation excluding those countries,
so that distribution is permitted only in or among countries not thus
excluded. In such case, this License incorporates the limitation as if
written in the body of this License.
13. The Free Software Foundation may publish revised and/or new
versions of the Lesser General Public License from time to time.
Such new versions will be similar in spirit to the present version,
but may differ in detail to address new problems or concerns.
Each version is given a distinguishing version number. If the Library
specifies a version number of this License which applies to it and
"any later version", you have the option of following the terms and
conditions either of that version or of any later version published by
the Free Software Foundation. If the Library does not specify a
license version number, you may choose any version ever published by
the Free Software Foundation.
14. If you wish to incorporate parts of the Library into other free
programs whose distribution conditions are incompatible with these,
write to the author to ask for permission. For software which is
copyrighted by the Free Software Foundation, write to the Free
Software Foundation; we sometimes make exceptions for this. Our
decision will be guided by the two goals of preserving the free status
of all derivatives of our free software and of promoting the sharing
and reuse of software generally.
NO WARRANTY
15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
DAMAGES.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Libraries
If you develop a new library, and you want it to be of the greatest
possible use to the public, we recommend making it free software that
everyone can redistribute and change. You can do so by permitting
redistribution under these terms (or, alternatively, under the terms of the
ordinary General Public License).
To apply these terms, attach the following notices to the library. It is
safest to attach them to the start of each source file to most effectively
convey the exclusion of warranty; and each file should have at least the
"copyright" line and a pointer to where the full notice is found.
Copyright (C)
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Also add information on how to contact you by electronic and paper mail.
You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the library, if
necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the
library `Frob' (a library for tweaking knobs) written by James Random Hacker.
, 1 April 1990
Ty Coon, President of Vice
That's all there is to it!
sync-monitor-0.2+16.04.20160304/authenticator/ 0000755 0000156 0000165 00000000000 12666332257 021242 5 ustar pbuser pbgroup 0000000 0000000 sync-monitor-0.2+16.04.20160304/authenticator/syncmonitorhelper.url-dispatcher 0000644 0000156 0000165 00000000070 12666332064 027667 0 ustar pbuser pbgroup 0000000 0000000 [
{
"protocol": "syncmonitorhelper"
}
]
sync-monitor-0.2+16.04.20160304/authenticator/main.cpp 0000644 0000156 0000165 00000006253 12666332064 022674 0 ustar pbuser pbgroup 0000000 0000000 /*
* Copyright (C) 2015 Canonical, Ltd.
*
* 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; version 3.
*
* 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 .
*/
#include "config.h"
#include
#include
#include
#include
#include
#include
QVariantMap parseAccountArg(QStringList args)
{
//syncmonitor:///authenticate?id=%1&service=%2
Q_FOREACH(const QString &arg, args) {
if (arg.startsWith("syncmonitorhelper:///")) {
QUrl url = QUrl::fromPercentEncoding(arg.toUtf8());
QString methodName = url.path().right(url.path().length() -1);
if (methodName != "authenticate") {
return QVariantMap();
}
//convert items to map
QUrlQuery query(url);
QList > queryItemsPair = query.queryItems();
QMap queryItems;
for(int i=0; i < queryItemsPair.count(); i++) {
QPair item = queryItemsPair[i];
queryItems.insert(item.first, item.second);
}
if (queryItems.contains("id") && queryItems.contains("service")) {
QVariantMap info;
info.insert("accountId", queryItems.value("id"));
info.insert("serviceName", queryItems.value("service"));
return info;
} else {
return QVariantMap();
}
}
}
return QVariantMap();
}
int main(int argc, char **argv)
{
QCoreApplication::setOrganizationName("Canonical");
QCoreApplication::setOrganizationDomain("canonical.com");
QCoreApplication::setApplicationName("Sync Monitor Helper");
QGuiApplication *app = new QGuiApplication(argc, argv);
QVariantMap accountInfo = parseAccountArg(app->arguments());
if (accountInfo.isEmpty()) {
qWarning() << "Usage: sync-monitor-helper syncmonitorhelper:///authenticate?id=&service=connect(view->engine(), SIGNAL(quit()), SLOT(quit()));
view->setResizeMode(QQuickView::SizeRootObjectToView);
view->setTitle("Sync Monitor");
view->rootContext()->setContextProperty("ONLINE_ACCOUNT", accountInfo);
view->rootContext()->setContextProperty("GETTEXT_PACKAGE", GETTEXT_PACKAGE);
view->rootContext()->setContextProperty("GETTEXT_LOCALEDIR", GETTEXT_LOCALEDIR);
view->rootContext()->setContextProperty("GETTEXT_PACKAGE", GETTEXT_PACKAGE);
view->setSource(QUrl("qrc:/main.qml"));
qDebug() << accountInfo;
view->show();
app->exec();
delete view;
delete app;
return 0;
}
sync-monitor-0.2+16.04.20160304/authenticator/syncmonitorhelper.desktop.in 0000644 0000156 0000165 00000000325 12666332064 027022 0 ustar pbuser pbgroup 0000000 0000000 [Desktop Entry]
Name=Sync Monitor
Comment=Ask for online account authentication if the token expires
Exec=@SYNC_MONITOR_HELPER_INSTALL_PATH@@SYNC_MONITOR_HELPER_BIN@ %u
Terminal=false
Type=Application
Version=1.0
sync-monitor-0.2+16.04.20160304/authenticator/sync-monitor-helper.qrc 0000644 0000156 0000165 00000000127 12666332064 025663 0 ustar pbuser pbgroup 0000000 0000000
main.qml
sync-monitor-0.2+16.04.20160304/authenticator/main.qml 0000644 0000156 0000165 00000012611 12666332064 022676 0 ustar pbuser pbgroup 0000000 0000000 import QtQuick 2.2
import Ubuntu.Components 1.1
import Ubuntu.Components.ListItems 1.0 as ListItem
import Ubuntu.OnlineAccounts 0.1
MainView {
id: root
property bool accountFound: false
width: units.gu(40)
height: units.gu(71)
useDeprecatedToolbar: false
AccountServiceModel {
id: accountServiceModel
accountId: ONLINE_ACCOUNT.accountId
service: ONLINE_ACCOUNT.serviceName
onCountChanged: {
console.debug("Account count changed:" + count)
if ((count == 1) && (pageStack.depth == 0)) {
var _acc = {}
_acc["displayName"] = accountServiceModel.get(0, "displayName")
_acc["providerName"] = accountServiceModel.get(0, "providerName")
_acc["serviceName"] = accountServiceModel.get(0, "serviceName")
_acc["accountServiceHandle"] = accountServiceModel.get(0, "accountServiceHandle")
_acc["accountId"] = accountServiceModel.get(0, "accountId")
_acc["accountHandle"] = accountServiceModel.get(0, "accountHandle")
root.accountFound = true
pageStack.push(accountPageComponent, {"account" : _acc})
}
}
}
PageStack {
id: pageStack
Component.onCompleted: {
if (!root.accountFound) {
pageStack.push(loadingPageComponent)
accountNotFoundTimeout.start()
}
}
}
Timer {
id: accountNotFoundTimeout
interval: 5000
repeat: false
onTriggered: {
if (!root.accountFound) {
pageStack.push(accountNotFoundPageComponent)
}
}
}
Component {
id: loadingPageComponent
Page {
id: loadingPage
title: i18n.tr("Accounts")
ActivityIndicator {
id: activity
anchors.centerIn : parent
running: visible
visible: loadingPage.active
}
}
}
Component {
id: accountNotFoundPageComponent
Page {
id: accountNotFoundPage
title: i18n.tr("Accounts")
head.backAction: Action {
iconName: "back"
text: i18n.tr("Quit")
onTriggered: Qt.quit()
}
Label {
anchors.centerIn: parent
text: i18n.tr("Fail to load account information.")
}
}
}
Component {
id: accountPageComponent
Page {
id: accountPage
property var account
property bool loginInProcess: false
function getProviderIcon(providerName)
{
switch(providerName)
{
case "Google":
return "google"
default:
return "contact-group"
}
}
title: i18n.tr("Fail to sync")
head.backAction: Action {
iconName: "back"
text: i18n.tr("Quit")
onTriggered: Qt.quit()
}
AccountService {
id: accountService
objectHandle: accountPage.account.accountServiceHandle
onAuthenticated: {
accountPage.loginInProcess = false
Qt.quit()
}
onAuthenticationError: {
accountPage.loginInProcess = false
console.log("Authentication failed, code " + error.code)
}
}
Column {
anchors {
verticalCenter: parent.verticalCenter
left: parent.left
right: parent.right
margins: units.gu(2)
}
spacing: units.gu(4)
width: parent.width
visible: !accountPage.loginInProcess
Label {
id: lblTitle
anchors {
left: parent.left
right: parent.right
}
text: i18n.tr("Your account failed to authenticate while syncing. Please click below to re-authenticate.")
wrapMode: Text.WordWrap
horizontalAlignment: Text.AlignHCenter
fontSize: "large"
}
Button {
anchors {
left: parent.left
right: parent.right
}
text: accountPage.account.displayName
iconName: accountPage.getProviderIcon(accountPage.account.providerName)
onClicked: {
if (!accountPage.busy) {
accountPage.loginInProcess = true
accountService.authenticate(null)
}
}
}
}
ActivityIndicator {
id: activity
anchors.centerIn: parent
running: visible
visible: accountPage.loginInProcess
}
}
}
Component.onCompleted: {
i18n.domain = GETTEXT_PACKAGE
i18n.bindtextdomain(GETTEXT_PACKAGE, GETTEXT_LOCALEDIR)
}
}
sync-monitor-0.2+16.04.20160304/authenticator/CMakeLists.txt 0000644 0000156 0000165 00000002031 12666332064 023772 0 ustar pbuser pbgroup 0000000 0000000 project(sync-monitor-helper)
set(SYNC_MONITOR_HELPER_BIN sync-monitor-helper)
QT5_ADD_RESOURCES(SYNC_MONITOR_HELPER_RC
sync-monitor-helper.qrc
)
include_directories(
${CMAKE_BINARY_DIR}
)
add_executable(${SYNC_MONITOR_HELPER_BIN}
main.cpp
${SYNC_MONITOR_HELPER_RC}
)
qt5_use_modules(${SYNC_MONITOR_HELPER_BIN} Core Gui Quick)
set(SYNC_MONITOR_HELPER_QMLS
main.qml
)
set(SYNC_MONITOR_HELPER_INSTALL_PATH
${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}/sync-monitor/
)
install(FILES "syncmonitorhelper.url-dispatcher"
DESTINATION ${CMAKE_INSTALL_DATADIR}/url-dispatcher/urls
)
configure_file(syncmonitorhelper.desktop.in syncmonitorhelper.desktop)
install(FILES "${CMAKE_CURRENT_BINARY_DIR}/syncmonitorhelper.desktop"
DESTINATION ${CMAKE_INSTALL_DATADIR}/applications
)
install(TARGETS ${SYNC_MONITOR_HELPER_BIN}
RUNTIME DESTINATION ${SYNC_MONITOR_HELPER_INSTALL_PATH})
# make the files visible on qtcreator
add_custom_target(sync_monitor_helper_QMlFiles ALL SOURCES ${SYNC_MONITOR_HELPER_QMLS})
sync-monitor-0.2+16.04.20160304/po/ 0000755 0000156 0000165 00000000000 12666332257 017006 5 ustar pbuser pbgroup 0000000 0000000 sync-monitor-0.2+16.04.20160304/po/sync-monitor.pot 0000644 0000156 0000165 00000006041 12666332064 022170 0 ustar pbuser pbgroup 0000000 0000000 # SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR Canonical Ltd.
# This file is distributed under the same license as the PACKAGE package.
# FIRST AUTHOR , YEAR.
#
#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: sync-monitor\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2015-03-23 16:48-0300\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME \n"
"Language-Team: LANGUAGE \n"
"Language: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=CHARSET\n"
"Content-Transfer-Encoding: 8bit\n"
#: src/sync-daemon.cpp:388
#, qt-format
msgid "Account %1 removed. Do you want to keep the account data?"
msgstr ""
#: authenticator/main.qml:66 authenticator/main.qml:84
msgid "Accounts"
msgstr ""
#: src/sync-account.cpp:551
msgid "Command not allowed"
msgstr ""
#: src/sync-account.cpp:571
msgid "Connection certificate has expired"
msgstr ""
#: src/sync-account.cpp:573
msgid "Connection certificate is invalid"
msgstr ""
#: src/sync-account.cpp:569
msgid "Connection timeout"
msgstr ""
#: qbuild/po/tmp/contacts-sync.application.in.h:1
msgid "Contacts"
msgstr ""
#: src/sync-account.cpp:556
msgid "Disk full"
msgstr ""
#: src/sync-account.cpp:577
msgid "Fail to connect with the server"
msgstr ""
#: authenticator/main.qml:94
msgid "Fail to load account information."
msgstr ""
#: src/sync-account.cpp:560
msgid "Fail to run \"two-way\" sync"
msgstr ""
#: authenticator/main.qml:119
msgid "Fail to sync"
msgstr ""
#: src/sync-daemon.cpp:507
#, qt-format
msgid ""
"Fail to sync %1 (%2).\n"
"%3"
msgstr ""
#: src/sync-account.cpp:558
msgid "Fail to sync due some remote problem"
msgstr ""
#: src/sync-account.cpp:562
msgid "Fail to sync some items"
msgstr ""
#: src/sync-account.cpp:547
msgid "Forbidden / access denied"
msgstr ""
#: src/notify-message.cpp:88
msgid "No"
msgstr ""
#: src/sync-account.cpp:549
msgid "Object not found / unassigned field"
msgstr ""
#: src/sync-account.cpp:564
msgid "Process unexpected die."
msgstr ""
#: src/sync-account.cpp:554
msgid "Proxy authentication required"
msgstr ""
#: authenticator/main.qml:88 authenticator/main.qml:123
msgid "Quit"
msgstr ""
#: src/sync-account.cpp:580
msgid "Server not found"
msgstr ""
#: src/sync-account.cpp:567
msgid "Server sent bad content"
msgstr ""
#: src/sync-daemon.cpp:442
#, qt-format
msgid "Start sync: %1 (%2)"
msgstr ""
#: src/sync-daemon.cpp:467
#, qt-format
msgid "Sync done: %1 (%2)"
msgstr ""
#: src/sync-daemon.cpp:387 src/sync-daemon.cpp:419 src/sync-daemon.cpp:441
#: src/sync-daemon.cpp:466 src/sync-daemon.cpp:506
msgid "Synchronization"
msgstr ""
#: qbuild/po/tmp/contacts-sync.application.in.h:2
msgid "Synchronize your contacts"
msgstr ""
#: src/sync-account.cpp:582
msgid "Unknown status"
msgstr ""
#: src/notify-message.cpp:83
msgid "Yes"
msgstr ""
#: src/sync-daemon.cpp:420
msgid ""
"Your access key is not valid anymore. Do you want to re-authenticate it?."
msgstr ""
#: authenticator/main.qml:160
msgid ""
"Your account failed to authenticate while syncing. Please click below to re-"
"authenticate."
msgstr ""
sync-monitor-0.2+16.04.20160304/po/CMakeLists.txt 0000644 0000156 0000165 00000003707 12666332064 021551 0 ustar pbuser pbgroup 0000000 0000000 project(sync-monitor-translations)
# for dh_translations to extract the domain
# (regarding syntax consistency, see http://pad.lv/1181187)
set (GETTEXT_PACKAGE "sync-monitor")
include(FindGettext)
set(DOMAIN sync-monitor)
set(POT_FILE ${DOMAIN}.pot)
file(GLOB PO_FILES *.po)
file(GLOB_RECURSE I18N_SRCS RELATIVE ${CMAKE_SOURCE_DIR}
${CMAKE_SOURCE_DIR}/src/*.cpp
)
file(GLOB_RECURSE I18N_XMLS RELATIVE ${CMAKE_CURRENT_BINARY_DIR}
${CMAKE_SOURCE_DIR}/accounts/applications/*.in
)
file(GLOB_RECURSE I18N_QMLS RELATIVE ${CMAKE_SOURCE_DIR}
${sync-monitor-helper_SOURCE_DIR}/*.qml
)
string(REPLACE "${CMAKE_SOURCE_DIR}/" "" RELATIVE_BUILD_DIR ${CMAKE_CURRENT_BINARY_DIR})
foreach(XML_FILE ${I18N_XMLS})
get_filename_component(XML_BASE_NAME ${XML_FILE} NAME)
list(APPEND I18N_SRCS "${RELATIVE_BUILD_DIR}/tmp/${XML_BASE_NAME}.h")
endforeach(XML_FILE)
foreach(PO_FILE ${PO_FILES})
get_filename_component(LANG ${PO_FILE} NAME_WE)
gettext_process_po_files(${LANG} ALL PO_FILES ${PO_FILE})
set(INSTALL_DIR ${CMAKE_INSTALL_LOCALEDIR}/${LANG}/LC_MESSAGES)
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/${LANG}.gmo
DESTINATION ${INSTALL_DIR}
RENAME ${DOMAIN}.mo)
endforeach(PO_FILE)
find_program(XGETTEXT_EXECUTABLE xgettext)
if(XGETTEXT_EXECUTABLE)
add_custom_target(${POT_FILE})
add_custom_command(TARGET ${POT_FILE}
COMMAND ${INTLTOOL_EXTRACT_EXECUTABLE}
-l --type=gettext/xml ${I18N_XMLS}
COMMAND ${XGETTEXT_EXECUTABLE} -o ${POT_FILE}
--c++ --qt --add-comments=TRANSLATORS
--keyword=_ --keyword=N_
--keyword=tr --keyword=tr:1,2
--keyword=dtr:2 --keyword=dtr:2,3
--package-name=${DOMAIN}
--copyright-holder='Canonical Ltd.'
-D ${CMAKE_SOURCE_DIR} ${I18N_QMLS}
-D ${CMAKE_SOURCE_DIR} ${I18N_SRCS}
-s -p ${CMAKE_CURRENT_SOURCE_DIR} ${I18N_SRCS}
)
endif()
sync-monitor-0.2+16.04.20160304/po/POTFILES.in 0000644 0000156 0000165 00000000052 12666332064 020554 0 ustar pbuser pbgroup 0000000 0000000 src/sync-account.cpp
src/sync-daemon.cpp
sync-monitor-0.2+16.04.20160304/config.h.in 0000644 0000156 0000165 00000002032 12666332064 020404 0 ustar pbuser pbgroup 0000000 0000000 /*
* Copyright 2014 Canonical Ltd.
*
* This file is part of sync-monitor.
*
* sync-monitor 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; version 3.
*
* contact-service-app 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 .
*/
#ifndef __CONFIG_H__
#define __CONFIG_H__
#define PROVIDER_TEMPLATE_PATH "@CMAKE_INSTALL_FULL_DATADIR@/sync-monitor/templates"
#define CONTACTS_SERVICE_NAME "contacts"
#define CALENDAR_SERVICE_NAME "calendar"
#define GETTEXT_LOCALEDIR "@CMAKE_INSTALL_FULL_LOCALEDIR@"
#define GETTEXT_PACKAGE "sync-monitor"
#endif
sync-monitor-0.2+16.04.20160304/cmake_uninstall.cmake.in 0000644 0000156 0000165 00000001654 12666332064 023152 0 ustar pbuser pbgroup 0000000 0000000 IF(NOT EXISTS "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt")
MESSAGE(FATAL_ERROR "Cannot find install manifest: \"@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt\"")
ENDIF(NOT EXISTS "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt")
FILE(READ "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt" files)
STRING(REGEX REPLACE "\n" ";" files "${files}")
FOREACH(file ${files})
MESSAGE(STATUS "Uninstalling \"$ENV{DESTDIR}${file}\"")
IF(EXISTS "$ENV{DESTDIR}${file}")
EXEC_PROGRAM(
"@CMAKE_COMMAND@" ARGS "-E remove \"$ENV{DESTDIR}${file}\""
OUTPUT_VARIABLE rm_out
RETURN_VALUE rm_retval
)
IF(NOT "${rm_retval}" STREQUAL 0)
MESSAGE(FATAL_ERROR "Problem when removing \"$ENV{DESTDIR}${file}\"")
ENDIF(NOT "${rm_retval}" STREQUAL 0)
ELSE(EXISTS "$ENV{DESTDIR}${file}")
MESSAGE(STATUS "File \"$ENV{DESTDIR}${file}\" does not exist.")
ENDIF(EXISTS "$ENV{DESTDIR}${file}")
ENDFOREACH(file)
sync-monitor-0.2+16.04.20160304/Ubuntu/ 0000755 0000156 0000165 00000000000 12666332257 017652 5 ustar pbuser pbgroup 0000000 0000000 sync-monitor-0.2+16.04.20160304/Ubuntu/SyncMonitor/ 0000755 0000156 0000165 00000000000 12666332257 022136 5 ustar pbuser pbgroup 0000000 0000000 sync-monitor-0.2+16.04.20160304/Ubuntu/SyncMonitor/plugin.h 0000644 0000156 0000165 00000001747 12666332064 023612 0 ustar pbuser pbgroup 0000000 0000000 /*
* Copyright 2014 Canonical Ltd.
*
* This file is part of sync-monitor.
*
* sync-monitor 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; version 3.
*
* contact-service-app 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 .
*/
#ifndef SYNCMONITOR_QML_PLUGIN_H
#define SYNCMONITOR_QML_PLUGIN_H
#include
class SyncMonitorPlugin : public QQmlExtensionPlugin
{
Q_OBJECT
Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QQmlExtensionInterface")
public:
void registerTypes(const char *uri);
};
#endif //SYNCMONITOR_QML_PLUGIN_H
sync-monitor-0.2+16.04.20160304/Ubuntu/SyncMonitor/plugin.cpp 0000644 0000156 0000165 00000001600 12666332064 024131 0 ustar pbuser pbgroup 0000000 0000000 /*
* Copyright 2014 Canonical Ltd.
*
* This file is part of sync-monitor.
*
* sync-monitor 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; version 3.
*
* contact-service-app 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 .
*/
#include "plugin.h"
#include "syncmonitor-qml.h"
#include
void SyncMonitorPlugin::registerTypes(const char *uri)
{
// @uri Ubuntu.SyncMonitor
qmlRegisterType(uri, 0, 1, "SyncMonitor");
}
sync-monitor-0.2+16.04.20160304/Ubuntu/SyncMonitor/syncmonitor-qml.cpp 0000644 0000156 0000165 00000006547 12666332064 026025 0 ustar pbuser pbgroup 0000000 0000000 /*
* Copyright 2014 Canonical Ltd.
*
* This file is part of sync-monitor.
*
* sync-monitor 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; version 3.
*
* contact-service-app 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 .
*/
#include
#include "syncmonitor-qml.h"
#define SYNCMONITOR_DBUS_SERVICE_NAME "com.canonical.SyncMonitor"
#define SYNCMONITOR_DBUS_OBJECT_PATH "/com/canonical/SyncMonitor"
#define SYNCMONITOR_DBUS_INTERFACE "com.canonical.SyncMonitor"
/*!
\qmltype SyncMonitor
\inqmlmodule Ubuntu.SyncMonitor 0.1
\brief The SyncMonitor is a helper class to get access to SyncMonitor Daemon
\b{This component is under heavy development.}
Example:
\qml
Item {
SyncMonitor {
id: syncMonitor
}
Button {
text: "sync"
onClick: syncMonitor.sync(["calendar", ["contacts"])
}
}
\endqml
*/
SyncMonitorQml::SyncMonitorQml(QObject *parent)
: QObject(parent),
m_iface(0)
{
}
SyncMonitorQml::~SyncMonitorQml()
{
if (m_iface) {
m_iface->call("detach");
delete m_iface;
m_iface = 0;
}
}
/*!
Specifies the current sync monitor state
\list
\li "idle" - Service is in idle state
\li "syncing" - Service is running a sync
\endlist
\qmlproperty string state
*/
QString SyncMonitorQml::state() const
{
if (m_iface) {
return m_iface->property("state").toString();
} else {
return "";
}
}
/*!
Specifies the enabled services to sync
\qmlproperty list enabledServices
*/
QStringList SyncMonitorQml::enabledServices() const
{
if (m_iface) {
return m_iface->property("enabledServices").toStringList();
} else {
return QStringList();
}
}
void SyncMonitorQml::classBegin()
{
}
void SyncMonitorQml::componentComplete()
{
m_iface = new QDBusInterface(SYNCMONITOR_DBUS_SERVICE_NAME,
SYNCMONITOR_DBUS_OBJECT_PATH,
SYNCMONITOR_DBUS_INTERFACE);
if (m_iface->lastError().isValid()) {
qWarning() << "Fail to connect with sync monitor:" << m_iface->lastError();
return;
}
connect(m_iface, SIGNAL(stateChanged()), SIGNAL(stateChanged()));
connect(m_iface, SIGNAL(enabledServicesChanged()), SIGNAL(enabledServicesChanged()));
m_iface->call("attach");
Q_EMIT stateChanged();
Q_EMIT enabledServicesChanged();
}
/*!
Start a new sync for specified services
*/
void SyncMonitorQml::sync(const QStringList &services)
{
if (m_iface) {
m_iface->call("sync", services);
}
}
/*!
Cancel current sync for specified services
*/
void SyncMonitorQml::cancel(const QStringList &services)
{
if (m_iface) {
m_iface->call("cancel", services);
}
}
/*!
Chek if a specific service is enabled or not
*/
bool SyncMonitorQml::serviceIsEnabled(const QString &service)
{
return enabledServices().contains(service);
}
sync-monitor-0.2+16.04.20160304/Ubuntu/SyncMonitor/syncmonitor-qml.h 0000644 0000156 0000165 00000003361 12666332064 025461 0 ustar pbuser pbgroup 0000000 0000000 /*
* Copyright 2014 Canonical Ltd.
*
* This file is part of sync-monitor.
*
* sync-monitor 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; version 3.
*
* contact-service-app 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 .
*/
#ifndef SYNCMONITOR_QML_H
#define SYNCMONITOR_QML_H
#include
#include
#include
class SyncMonitorQml : public QObject, public QQmlParserStatus
{
Q_OBJECT
Q_INTERFACES(QQmlParserStatus)
Q_PROPERTY(QString state READ state NOTIFY stateChanged)
Q_PROPERTY(QStringList enabledServices READ enabledServices NOTIFY enabledServicesChanged)
public:
SyncMonitorQml(QObject *parent = 0);
~SyncMonitorQml();
QString state() const;
QStringList enabledServices() const;
void classBegin();
void componentComplete();
Q_SIGNALS:
void syncStarted(const QString &account, const QString &service);
void syncFinished(const QString &account, const QString &service);
void syncError(const QString &account, const QString &service, const QString &error);
void stateChanged();
void enabledServicesChanged();
public Q_SLOTS:
void sync(const QStringList &services);
void cancel(const QStringList &services);
bool serviceIsEnabled(const QString &service);
private:
QDBusInterface *m_iface;
};
#endif
sync-monitor-0.2+16.04.20160304/Ubuntu/SyncMonitor/qmldir 0000644 0000156 0000165 00000000061 12666332064 023342 0 ustar pbuser pbgroup 0000000 0000000 module Ubuntu.SyncMonitor
plugin syncmonitor-qml
sync-monitor-0.2+16.04.20160304/Ubuntu/SyncMonitor/CMakeLists.txt 0000644 0000156 0000165 00000001333 12666332064 024672 0 ustar pbuser pbgroup 0000000 0000000 set(SYNC_MONITOR_QML_SRC
plugin.h
plugin.cpp
syncmonitor-qml.h
syncmonitor-qml.cpp
)
set(SYNC_MONITOR_QML_FILES
qmldir
)
add_library(syncmonitor-qml SHARED ${SYNC_MONITOR_QML_SRC})
qt5_use_modules(syncmonitor-qml Core Qml DBus)
execute_process(
COMMAND qmake -query QT_INSTALL_QML
OUTPUT_VARIABLE QT_INSTALL_QML
OUTPUT_STRIP_TRAILING_WHITESPACE
)
set(SYNCMONITOR_QML_INSTALL_DIR ${QT_INSTALL_QML}/Ubuntu/SyncMonitor)
install(TARGETS syncmonitor-qml DESTINATION ${SYNCMONITOR_QML_INSTALL_DIR})
install(FILES ${SYNC_MONITOR_QML_FILES} DESTINATION ${SYNCMONITOR_QML_INSTALL_DIR})
# make the files visible on qtcreator
add_custom_target(syncmonitor_QmlFiles ALL SOURCES ${SYNC_MONITOR_QML_FILES})
sync-monitor-0.2+16.04.20160304/Ubuntu/CMakeLists.txt 0000644 0000156 0000165 00000000036 12666332064 022405 0 ustar pbuser pbgroup 0000000 0000000 add_subdirectory(SyncMonitor)
sync-monitor-0.2+16.04.20160304/3rd_party/ 0000755 0000156 0000165 00000000000 12666332257 020277 5 ustar pbuser pbgroup 0000000 0000000 sync-monitor-0.2+16.04.20160304/3rd_party/gmock/ 0000755 0000156 0000165 00000000000 12666332257 021377 5 ustar pbuser pbgroup 0000000 0000000 sync-monitor-0.2+16.04.20160304/3rd_party/gmock/src/ 0000755 0000156 0000165 00000000000 12666332257 022166 5 ustar pbuser pbgroup 0000000 0000000 sync-monitor-0.2+16.04.20160304/3rd_party/gmock/src/gmock_main.cc 0000644 0000156 0000165 00000005041 12666332064 024575 0 ustar pbuser pbgroup 0000000 0000000 // Copyright 2008, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// Author: wan@google.com (Zhanyong Wan)
#include
#include "gmock/gmock.h"
#include "gtest/gtest.h"
// MS C++ compiler/linker has a bug on Windows (not on Windows CE), which
// causes a link error when _tmain is defined in a static library and UNICODE
// is enabled. For this reason instead of _tmain, main function is used on
// Windows. See the following link to track the current status of this bug:
// http://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=394464 // NOLINT
#if GTEST_OS_WINDOWS_MOBILE
# include // NOLINT
GTEST_API_ int _tmain(int argc, TCHAR** argv) {
#else
GTEST_API_ int main(int argc, char** argv) {
#endif // GTEST_OS_WINDOWS_MOBILE
std::cout << "Running main() from gmock_main.cc\n";
// Since Google Mock depends on Google Test, InitGoogleMock() is
// also responsible for initializing Google Test. Therefore there's
// no need for calling testing::InitGoogleTest() separately.
testing::InitGoogleMock(&argc, argv);
return RUN_ALL_TESTS();
}
sync-monitor-0.2+16.04.20160304/3rd_party/gmock/src/gmock.cc 0000644 0000156 0000165 00000015462 12666332064 023601 0 ustar pbuser pbgroup 0000000 0000000 // Copyright 2008, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// Author: wan@google.com (Zhanyong Wan)
#include "gmock/gmock.h"
#include "gmock/internal/gmock-port.h"
namespace testing {
// TODO(wan@google.com): support using environment variables to
// control the flag values, like what Google Test does.
GMOCK_DEFINE_bool_(catch_leaked_mocks, true,
"true iff Google Mock should report leaked mock objects "
"as failures.");
GMOCK_DEFINE_string_(verbose, internal::kWarningVerbosity,
"Controls how verbose Google Mock's output is."
" Valid values:\n"
" info - prints all messages.\n"
" warning - prints warnings and errors.\n"
" error - prints errors only.");
namespace internal {
// Parses a string as a command line flag. The string should have the
// format "--gmock_flag=value". When def_optional is true, the
// "=value" part can be omitted.
//
// Returns the value of the flag, or NULL if the parsing failed.
static const char* ParseGoogleMockFlagValue(const char* str,
const char* flag,
bool def_optional) {
// str and flag must not be NULL.
if (str == NULL || flag == NULL) return NULL;
// The flag must start with "--gmock_".
const std::string flag_str = std::string("--gmock_") + flag;
const size_t flag_len = flag_str.length();
if (strncmp(str, flag_str.c_str(), flag_len) != 0) return NULL;
// Skips the flag name.
const char* flag_end = str + flag_len;
// When def_optional is true, it's OK to not have a "=value" part.
if (def_optional && (flag_end[0] == '\0')) {
return flag_end;
}
// If def_optional is true and there are more characters after the
// flag name, or if def_optional is false, there must be a '=' after
// the flag name.
if (flag_end[0] != '=') return NULL;
// Returns the string after "=".
return flag_end + 1;
}
// Parses a string for a Google Mock bool flag, in the form of
// "--gmock_flag=value".
//
// On success, stores the value of the flag in *value, and returns
// true. On failure, returns false without changing *value.
static bool ParseGoogleMockBoolFlag(const char* str, const char* flag,
bool* value) {
// Gets the value of the flag as a string.
const char* const value_str = ParseGoogleMockFlagValue(str, flag, true);
// Aborts if the parsing failed.
if (value_str == NULL) return false;
// Converts the string value to a bool.
*value = !(*value_str == '0' || *value_str == 'f' || *value_str == 'F');
return true;
}
// Parses a string for a Google Mock string flag, in the form of
// "--gmock_flag=value".
//
// On success, stores the value of the flag in *value, and returns
// true. On failure, returns false without changing *value.
static bool ParseGoogleMockStringFlag(const char* str, const char* flag,
std::string* value) {
// Gets the value of the flag as a string.
const char* const value_str = ParseGoogleMockFlagValue(str, flag, false);
// Aborts if the parsing failed.
if (value_str == NULL) return false;
// Sets *value to the value of the flag.
*value = value_str;
return true;
}
// The internal implementation of InitGoogleMock().
//
// The type parameter CharType can be instantiated to either char or
// wchar_t.
template
void InitGoogleMockImpl(int* argc, CharType** argv) {
// Makes sure Google Test is initialized. InitGoogleTest() is
// idempotent, so it's fine if the user has already called it.
InitGoogleTest(argc, argv);
if (*argc <= 0) return;
for (int i = 1; i != *argc; i++) {
const std::string arg_string = StreamableToString(argv[i]);
const char* const arg = arg_string.c_str();
// Do we see a Google Mock flag?
if (ParseGoogleMockBoolFlag(arg, "catch_leaked_mocks",
&GMOCK_FLAG(catch_leaked_mocks)) ||
ParseGoogleMockStringFlag(arg, "verbose", &GMOCK_FLAG(verbose))) {
// Yes. Shift the remainder of the argv list left by one. Note
// that argv has (*argc + 1) elements, the last one always being
// NULL. The following loop moves the trailing NULL element as
// well.
for (int j = i; j != *argc; j++) {
argv[j] = argv[j + 1];
}
// Decrements the argument count.
(*argc)--;
// We also need to decrement the iterator as we just removed
// an element.
i--;
}
}
}
} // namespace internal
// Initializes Google Mock. This must be called before running the
// tests. In particular, it parses a command line for the flags that
// Google Mock recognizes. Whenever a Google Mock flag is seen, it is
// removed from argv, and *argc is decremented.
//
// No value is returned. Instead, the Google Mock flag variables are
// updated.
//
// Since Google Test is needed for Google Mock to work, this function
// also initializes Google Test and parses its flags, if that hasn't
// been done.
GTEST_API_ void InitGoogleMock(int* argc, char** argv) {
internal::InitGoogleMockImpl(argc, argv);
}
// This overloaded version can be used in Windows programs compiled in
// UNICODE mode.
GTEST_API_ void InitGoogleMock(int* argc, wchar_t** argv) {
internal::InitGoogleMockImpl(argc, argv);
}
} // namespace testing
sync-monitor-0.2+16.04.20160304/3rd_party/gmock/src/gmock-matchers.cc 0000644 0000156 0000165 00000011456 12666332064 025404 0 ustar pbuser pbgroup 0000000 0000000 // Copyright 2007, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// Author: wan@google.com (Zhanyong Wan)
// Google Mock - a framework for writing C++ mock classes.
//
// This file implements Matcher, Matcher, and
// utilities for defining matchers.
#include "gmock/gmock-matchers.h"
#include "gmock/gmock-generated-matchers.h"
#include
#include
#include
namespace testing {
// Constructs a matcher that matches a const string& whose value is
// equal to s.
Matcher::Matcher(const internal::string& s) {
*this = Eq(s);
}
// Constructs a matcher that matches a const string& whose value is
// equal to s.
Matcher::Matcher(const char* s) {
*this = Eq(internal::string(s));
}
// Constructs a matcher that matches a string whose value is equal to s.
Matcher::Matcher(const internal::string& s) { *this = Eq(s); }
// Constructs a matcher that matches a string whose value is equal to s.
Matcher::Matcher(const char* s) {
*this = Eq(internal::string(s));
}
#if GTEST_HAS_STRING_PIECE_
// Constructs a matcher that matches a const StringPiece& whose value is
// equal to s.
Matcher::Matcher(const internal::string& s) {
*this = Eq(s);
}
// Constructs a matcher that matches a const StringPiece& whose value is
// equal to s.
Matcher::Matcher(const char* s) {
*this = Eq(internal::string(s));
}
// Constructs a matcher that matches a const StringPiece& whose value is
// equal to s.
Matcher::Matcher(StringPiece s) {
*this = Eq(s.ToString());
}
// Constructs a matcher that matches a StringPiece whose value is equal to s.
Matcher::Matcher(const internal::string& s) {
*this = Eq(s);
}
// Constructs a matcher that matches a StringPiece whose value is equal to s.
Matcher::Matcher(const char* s) {
*this = Eq(internal::string(s));
}
// Constructs a matcher that matches a StringPiece whose value is equal to s.
Matcher::Matcher(StringPiece s) {
*this = Eq(s.ToString());
}
#endif // GTEST_HAS_STRING_PIECE_
namespace internal {
// Joins a vector of strings as if they are fields of a tuple; returns
// the joined string.
GTEST_API_ string JoinAsTuple(const Strings& fields) {
switch (fields.size()) {
case 0:
return "";
case 1:
return fields[0];
default:
string result = "(" + fields[0];
for (size_t i = 1; i < fields.size(); i++) {
result += ", ";
result += fields[i];
}
result += ")";
return result;
}
}
// Returns the description for a matcher defined using the MATCHER*()
// macro where the user-supplied description string is "", if
// 'negation' is false; otherwise returns the description of the
// negation of the matcher. 'param_values' contains a list of strings
// that are the print-out of the matcher's parameters.
GTEST_API_ string FormatMatcherDescription(bool negation,
const char* matcher_name,
const Strings& param_values) {
string result = ConvertIdentifierNameToWords(matcher_name);
if (param_values.size() >= 1)
result += " " + JoinAsTuple(param_values);
return negation ? "not (" + result + ")" : result;
}
} // namespace internal
} // namespace testing
sync-monitor-0.2+16.04.20160304/3rd_party/gmock/src/gmock-spec-builders.cc 0000644 0000156 0000165 00000073022 12666332064 026334 0 ustar pbuser pbgroup 0000000 0000000 // Copyright 2007, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// Author: wan@google.com (Zhanyong Wan)
// Google Mock - a framework for writing C++ mock classes.
//
// This file implements the spec builder syntax (ON_CALL and
// EXPECT_CALL).
#include "gmock/gmock-spec-builders.h"
#include
#include // NOLINT
#include