Skip to content

Latest commit

 

History

History
803 lines (718 loc) · 29.7 KB

caldavclient.cpp

File metadata and controls

803 lines (718 loc) · 29.7 KB
 
1
/*
Mar 3, 2014
Mar 3, 2014
2
* This file is part of buteo-sync-plugin-caldav package
3
*
Mar 30, 2021
Mar 30, 2021
4
* Copyright (c) 2013 - 2021 Jolla Ltd. and/or its subsidiary(-ies).
May 7, 2020
May 7, 2020
5
* Copyright (c) 2020 Open Mobile Platform LLC.
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
*
* Contributors: Mani Chandrasekar <maninc@gmail.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License
* version 2.1 as published by the Free Software Foundation.
*
* 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 St, Fifth Floor, Boston, MA
* 02110-1301 USA
*
*/
#include "caldavclient.h"
Aug 14, 2019
Aug 14, 2019
26
#include "propfind.h"
Apr 10, 2014
Apr 10, 2014
27
#include "notebooksyncagent.h"
Apr 11, 2014
Apr 11, 2014
28
Mar 8, 2017
Mar 8, 2017
29
30
#include <sailfishkeyprovider_iniparser.h>
31
32
33
34
#include <extendedcalendar.h>
#include <extendedstorage.h>
#include <notebook.h>
Mar 4, 2014
Mar 4, 2014
35
#include <QNetworkAccessManager>
36
37
#include <QNetworkReply>
#include <QDateTime>
Sep 26, 2017
Sep 26, 2017
38
#include <QtGlobal>
Aug 18, 2021
Aug 18, 2021
39
#include <QStandardPaths>
40
41
42
43
44
#include <Accounts/Manager>
#include <Accounts/Account>
#include <PluginCbInterface.h>
Aug 18, 2021
Aug 18, 2021
45
#include "logging.h"
46
47
48
#include <ProfileEngineDefs.h>
#include <ProfileManager.h>
May 7, 2020
May 7, 2020
49
namespace {
Mar 8, 2017
Mar 8, 2017
50
May 7, 2020
May 7, 2020
51
52
53
54
55
56
57
58
const QString cleanSyncMarkersFileDir = QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation)
+ QStringLiteral("/system/privileged/Sync");
const QString cleanSyncMarkersFile = cleanSyncMarkersFileDir + QStringLiteral("/caldav.ini");
const char * const SYNC_PREV_PERIOD_KEY = "Sync Previous Months Span";
const char * const SYNC_NEXT_PERIOD_KEY = "Sync Next Months Span";
}
Sep 26, 2017
Sep 26, 2017
59
Mar 30, 2021
Mar 30, 2021
60
61
62
63
Buteo::ClientPlugin* CalDavClientLoader::createClientPlugin(
const QString& pluginName,
const Buteo::SyncProfile& profile,
Buteo::PluginCbInterface* cbInterface)
Feb 19, 2014
Feb 19, 2014
64
{
Mar 30, 2021
Mar 30, 2021
65
return new CalDavClient(pluginName, profile, cbInterface);
66
67
68
69
}
CalDavClient::CalDavClient(const QString& aPluginName,
const Buteo::SyncProfile& aProfile,
Feb 19, 2014
Feb 19, 2014
70
71
Buteo::PluginCbInterface *aCbInterface)
: ClientPlugin(aPluginName, aProfile, aCbInterface)
Apr 3, 2014
Apr 3, 2014
72
73
74
75
, mManager(0)
, mAuth(0)
, mCalendar(0)
, mStorage(0)
Apr 1, 2015
Apr 1, 2015
76
, mAccountId(0)
77
{
Aug 18, 2021
Aug 18, 2021
78
FUNCTION_CALL_TRACE(lcCalDavTrace);
79
80
}
Feb 19, 2014
Feb 19, 2014
81
82
CalDavClient::~CalDavClient()
{
Aug 18, 2021
Aug 18, 2021
83
FUNCTION_CALL_TRACE(lcCalDavTrace);
84
85
}
Feb 19, 2014
Feb 19, 2014
86
87
bool CalDavClient::init()
{
Aug 18, 2021
Aug 18, 2021
88
FUNCTION_CALL_TRACE(lcCalDavTrace);
89
Apr 3, 2014
Apr 3, 2014
90
mNAManager = new QNetworkAccessManager(this);
91
Feb 19, 2014
Feb 19, 2014
92
if (initConfig()) {
93
94
95
96
97
98
99
100
return true;
} else {
// Uninitialize everything that was initialized before failure.
uninit();
return false;
}
}
Feb 19, 2014
Feb 19, 2014
101
102
bool CalDavClient::uninit()
{
Aug 18, 2021
Aug 18, 2021
103
FUNCTION_CALL_TRACE(lcCalDavTrace);
104
105
106
return true;
}
Feb 19, 2014
Feb 19, 2014
107
108
bool CalDavClient::startSync()
{
Aug 18, 2021
Aug 18, 2021
109
FUNCTION_CALL_TRACE(lcCalDavTrace);
110
Oct 18, 2013
Oct 18, 2013
111
if (!mAuth)
112
113
return false;
Oct 18, 2013
Oct 18, 2013
114
mAuth->authenticate();
115
Aug 18, 2021
Aug 18, 2021
116
qCDebug(lcCalDav) << "Init done. Continuing with sync";
117
118
119
120
return true;
}
Feb 19, 2014
Feb 19, 2014
121
122
void CalDavClient::abortSync(Sync::SyncStatus aStatus)
{
Nov 5, 2019
Nov 5, 2019
123
Q_UNUSED(aStatus);
Aug 18, 2021
Aug 18, 2021
124
FUNCTION_CALL_TRACE(lcCalDavTrace);
Nov 5, 2019
Nov 5, 2019
125
126
127
128
129
for (NotebookSyncAgent *agent: mNotebookSyncAgents) {
disconnect(agent, &NotebookSyncAgent::finished,
this, &CalDavClient::notebookSyncFinished);
agent->abort();
}
Nov 5, 2019
Nov 5, 2019
130
syncFinished(Buteo::SyncResults::ABORTED, QLatin1String("Sync aborted"));
131
132
}
Feb 19, 2014
Feb 19, 2014
133
134
bool CalDavClient::cleanUp()
{
Aug 18, 2021
Aug 18, 2021
135
FUNCTION_CALL_TRACE(lcCalDavTrace);
Apr 3, 2014
Apr 3, 2014
136
137
138
139
140
// This function is called after the account has been deleted to allow the plugin to remove
// all the notebooks associated with the account.
QString accountIdString = iProfile.key(Buteo::KEY_ACCOUNT_ID);
Apr 10, 2014
Apr 10, 2014
141
142
int accountId = accountIdString.toInt();
if (accountId == 0) {
Aug 18, 2021
Aug 18, 2021
143
qCWarning(lcCalDav) << "profile does not specify" << Buteo::KEY_ACCOUNT_ID;
Apr 3, 2014
Apr 3, 2014
144
return false;
Oct 21, 2013
Oct 21, 2013
145
}
Feb 19, 2014
Feb 19, 2014
146
Apr 1, 2015
Apr 1, 2015
147
mAccountId = accountId;
Dec 18, 2020
Dec 18, 2020
148
mKCal::ExtendedCalendar::Ptr calendar = mKCal::ExtendedCalendar::Ptr(new mKCal::ExtendedCalendar(QTimeZone::utc()));
Apr 4, 2014
Apr 4, 2014
149
mKCal::ExtendedStorage::Ptr storage = mKCal::ExtendedCalendar::defaultStorage(calendar);
Apr 3, 2014
Apr 3, 2014
150
151
if (!storage->open()) {
calendar->close();
Aug 18, 2021
Aug 18, 2021
152
qCWarning(lcCalDav) << "unable to open calendar storage";
Apr 3, 2014
Apr 3, 2014
153
154
155
return false;
}
Apr 10, 2014
Apr 10, 2014
156
157
158
159
160
161
deleteNotebooksForAccount(accountId, calendar, storage);
storage->close();
calendar->close();
return true;
}
May 7, 2015
May 7, 2015
162
void CalDavClient::deleteNotebooksForAccount(int accountId, mKCal::ExtendedCalendar::Ptr, mKCal::ExtendedStorage::Ptr storage)
Apr 10, 2014
Apr 10, 2014
163
{
Aug 18, 2021
Aug 18, 2021
164
FUNCTION_CALL_TRACE(lcCalDavTrace);
Apr 10, 2014
Apr 10, 2014
165
Jun 19, 2017
Jun 19, 2017
166
167
168
if (storage) {
QString notebookAccountPrefix = QString::number(accountId) + "-"; // for historical reasons!
QString accountIdStr = QString::number(accountId);
Nov 14, 2019
Nov 14, 2019
169
const mKCal::Notebook::List notebookList = storage->notebooks();
Aug 18, 2021
Aug 18, 2021
170
qCDebug(lcCalDav) << "Total Number of Notebooks in device = " << notebookList.count();
Jun 19, 2017
Jun 19, 2017
171
int deletedCount = 0;
Nov 14, 2019
Nov 14, 2019
172
for (mKCal::Notebook::Ptr notebook : notebookList) {
Jun 19, 2017
Jun 19, 2017
173
174
175
176
if (notebook->account() == accountIdStr || notebook->account().startsWith(notebookAccountPrefix)) {
if (storage->deleteNotebook(notebook)) {
deletedCount++;
}
Apr 3, 2014
Apr 3, 2014
177
}
Oct 21, 2013
Oct 21, 2013
178
}
Aug 18, 2021
Aug 18, 2021
179
qCDebug(lcCalDav) << "Deleted" << deletedCount << "notebooks";
Oct 21, 2013
Oct 21, 2013
180
}
May 7, 2015
May 7, 2015
181
182
183
184
}
bool CalDavClient::cleanSyncRequired(int accountId)
{
May 7, 2020
May 7, 2020
185
186
187
static const QByteArray iniFileDir = cleanSyncMarkersFileDir.toUtf8();
static const QByteArray iniFile = cleanSyncMarkersFile.toUtf8();
Mar 8, 2017
Mar 8, 2017
188
189
190
// multiple CalDavClient processes might be spawned (e.g. sync with different accounts)
// so use a process mutex to ensure that only one will access the clean sync marker file at any time.
if (!mProcessMutex) {
May 7, 2020
May 7, 2020
191
mProcessMutex.reset(new Sailfish::KeyProvider::ProcessMutex(iniFile.constData()));
Mar 8, 2017
Mar 8, 2017
192
193
194
195
}
mProcessMutex->lock();
char *cleaned_value = SailfishKeyProvider_ini_read(
May 7, 2020
May 7, 2020
196
iniFile.constData(),
Mar 8, 2017
Mar 8, 2017
197
198
199
200
201
"General",
QStringLiteral("%1-cleaned").arg(accountId).toLatin1());
bool alreadyClean = cleaned_value != 0 && strncmp(cleaned_value, "true", 4) == 0;
free(cleaned_value);
May 7, 2015
May 7, 2015
202
203
if (!alreadyClean) {
// first, delete any data associated with this account, so this sync will be a clean sync.
Aug 18, 2021
Aug 18, 2021
204
qCWarning(lcCalDav) << "Deleting caldav notebooks associated with this account:" << accountId << "due to clean sync";
May 7, 2015
May 7, 2015
205
206
deleteNotebooksForAccount(accountId, mCalendar, mStorage);
// now delete notebooks for non-existent accounts.
Aug 18, 2021
Aug 18, 2021
207
qCWarning(lcCalDav) << "Deleting caldav notebooks associated with nonexistent accounts due to clean sync";
May 7, 2015
May 7, 2015
208
209
// a) find out which accounts are associated with each of our notebooks.
QList<int> notebookAccountIds;
Nov 14, 2019
Nov 14, 2019
210
211
const mKCal::Notebook::List allNotebooks = mStorage->notebooks();
for (mKCal::Notebook::Ptr nb : allNotebooks) {
May 7, 2015
May 7, 2015
212
213
214
215
216
217
218
219
220
221
222
QString nbAccount = nb->account();
if (!nbAccount.isEmpty() && nb->pluginName().contains(QStringLiteral("caldav"))) {
// caldav notebook->account() values used to be like: "55-/user/calendars/someCalendar"
int indexOfHyphen = nbAccount.indexOf('-');
if (indexOfHyphen > 0) {
// this is an old caldav notebook which used "accountId-remoteServerPath" form
nbAccount.chop(nbAccount.length() - indexOfHyphen);
}
bool ok = true;
int notebookAccountId = nbAccount.toInt(&ok);
if (!ok) {
Aug 18, 2021
Aug 18, 2021
223
qCWarning(lcCalDav) << "notebook account value was strange:" << nb->account() << "->" << nbAccount << "->" << "not ok";
May 7, 2015
May 7, 2015
224
} else {
Aug 18, 2021
Aug 18, 2021
225
qCWarning(lcCalDav) << "found account id:" << notebookAccountId << "for" << nb->account() << "->" << nbAccount;
May 7, 2015
May 7, 2015
226
227
228
229
230
231
232
233
if (!notebookAccountIds.contains(notebookAccountId)) {
notebookAccountIds.append(notebookAccountId);
}
}
}
}
// b) find out if any of those accounts don't exist - if not,
Accounts::AccountIdList accountIdList = mManager->accountList();
Nov 14, 2019
Nov 14, 2019
234
for (int notebookAccountId : const_cast<const QList<int>&>(notebookAccountIds)) {
May 7, 2015
May 7, 2015
235
if (!accountIdList.contains(notebookAccountId)) {
Aug 18, 2021
Aug 18, 2021
236
qCWarning(lcCalDav) << "purging notebooks for deleted caldav account" << notebookAccountId;
May 7, 2015
May 7, 2015
237
238
239
240
deleteNotebooksForAccount(notebookAccountId, mCalendar, mStorage);
}
}
Mar 8, 2017
Mar 8, 2017
241
242
// mark this account as having been cleaned.
if (SailfishKeyProvider_ini_write(
May 7, 2020
May 7, 2020
243
244
iniFileDir.constData(),
iniFile.constData(),
Mar 8, 2017
Mar 8, 2017
245
246
247
"General",
QStringLiteral("%1-cleaned").arg(accountId).toLatin1(),
"true") != 0) {
Aug 18, 2021
Aug 18, 2021
248
qCWarning(lcCalDav) << "Failed to mark account as clean! Next sync will be unnecessarily cleaned also!";
Mar 8, 2017
Mar 8, 2017
249
250
}
May 7, 2015
May 7, 2015
251
// finished; return true because this will be a clean sync.
Aug 18, 2021
Aug 18, 2021
252
qCWarning(lcCalDav) << "Finished pre-sync cleanup with caldav account" << accountId;
Mar 8, 2017
Mar 8, 2017
253
mProcessMutex->unlock();
May 7, 2015
May 7, 2015
254
return true;
Apr 3, 2014
Apr 3, 2014
255
}
May 7, 2015
May 7, 2015
256
Mar 8, 2017
Mar 8, 2017
257
mProcessMutex->unlock();
May 7, 2015
May 7, 2015
258
return false;
259
260
}
Feb 19, 2014
Feb 19, 2014
261
262
void CalDavClient::connectivityStateChanged(Sync::ConnectivityType aType, bool aState)
{
Aug 18, 2021
Aug 18, 2021
263
264
FUNCTION_CALL_TRACE(lcCalDavTrace);
qCDebug(lcCalDav) << "Received connectivity change event:" << aType << " changed to " << aState;
Apr 16, 2015
Apr 16, 2015
265
266
267
268
if (aType == Sync::CONNECTIVITY_INTERNET && !aState) {
// we lost connectivity during sync.
abortSync(Sync::SYNC_CONNECTION_ERROR);
}
269
270
}
Apr 7, 2020
Apr 7, 2020
271
Accounts::Account* CalDavClient::getAccountForCalendars(Accounts::Service *service) const
Aug 14, 2019
Aug 14, 2019
272
{
Apr 7, 2020
Apr 7, 2020
273
Accounts::Account *account = mManager->account(mAccountId);
Aug 14, 2019
Aug 14, 2019
274
if (!account) {
Aug 18, 2021
Aug 18, 2021
275
qCWarning(lcCalDav) << "cannot find account" << mAccountId;
Aug 14, 2019
Aug 14, 2019
276
277
278
return NULL;
}
if (!account->enabled()) {
Aug 18, 2021
Aug 18, 2021
279
qCWarning(lcCalDav) << "Account" << mAccountId << "is disabled!";
Aug 14, 2019
Aug 14, 2019
280
281
return NULL;
}
Aug 14, 2019
Aug 14, 2019
282
Accounts::Service calendarService;
Nov 14, 2019
Nov 14, 2019
283
284
const Accounts::ServiceList caldavServices = account->services("caldav");
for (const Accounts::Service &currService : caldavServices) {
Aug 14, 2019
Aug 14, 2019
285
account->selectService(currService);
Apr 7, 2020
Apr 7, 2020
286
if (account->value("caldav-sync/profile_id").toString() == getProfileName()) {
Aug 14, 2019
Aug 14, 2019
287
calendarService = currService;
Aug 14, 2019
Aug 14, 2019
288
289
290
break;
}
}
Aug 14, 2019
Aug 14, 2019
291
if (!calendarService.isValid()) {
Aug 18, 2021
Aug 18, 2021
292
qCWarning(lcCalDav) << "cannot find a service for account" << mAccountId << "with a valid calendar list";
Aug 14, 2019
Aug 14, 2019
293
294
295
return NULL;
}
Aug 14, 2019
Aug 14, 2019
296
account->selectService(calendarService);
Aug 14, 2019
Aug 14, 2019
297
if (!account->enabled()) {
Aug 18, 2021
Aug 18, 2021
298
qCWarning(lcCalDav) << "Account" << mAccountId << "service:" << service->name() << "is disabled!";
Aug 14, 2019
Aug 14, 2019
299
300
301
return NULL;
}
Aug 14, 2019
Aug 14, 2019
302
303
304
if (service) {
*service = calendarService;
}
Aug 14, 2019
Aug 14, 2019
305
306
307
return account;
}
Aug 14, 2019
Aug 14, 2019
308
309
310
311
312
313
314
315
316
317
318
319
struct CalendarSettings
{
public:
CalendarSettings(Accounts::Account *account)
: paths(account->value("calendars").toStringList())
, displayNames(account->value("calendar_display_names").toStringList())
, colors(account->value("calendar_colors").toStringList())
, enabled(account->value("enabled_calendars").toStringList())
{
if (enabled.count() > paths.count()
|| paths.count() != displayNames.count()
|| paths.count() != colors.count()) {
Aug 18, 2021
Aug 18, 2021
320
qCWarning(lcCalDav) << "Bad calendar data for account" << account->id();
Aug 14, 2019
Aug 14, 2019
321
322
323
324
325
326
paths.clear();
displayNames.clear();
colors.clear();
enabled.clear();
}
};
Apr 6, 2020
Apr 6, 2020
327
328
// Constructs a list of CalendarInfo from value stored in settings.
QList<PropFind::CalendarInfo> toCalendars()
Aug 14, 2019
Aug 14, 2019
329
{
Apr 6, 2020
Apr 6, 2020
330
QList<PropFind::CalendarInfo> allCalendarInfo;
Aug 14, 2019
Aug 14, 2019
331
for (int i = 0; i < paths.count(); i++) {
Apr 6, 2020
Apr 6, 2020
332
333
allCalendarInfo << PropFind::CalendarInfo(paths[i],
displayNames[i], colors[i]);
Apr 6, 2020
Apr 6, 2020
334
335
336
337
338
339
340
341
}
return allCalendarInfo;
};
QList<PropFind::CalendarInfo> enabledCalendars(const QList<PropFind::CalendarInfo> &calendars)
{
QList<PropFind::CalendarInfo> filteredCalendarInfo;
for (const PropFind::CalendarInfo &info : calendars) {
if (!enabled.contains(info.remotePath)) {
Aug 14, 2019
Aug 14, 2019
342
343
continue;
}
Apr 6, 2020
Apr 6, 2020
344
filteredCalendarInfo << info;
Aug 14, 2019
Aug 14, 2019
345
}
Apr 6, 2020
Apr 6, 2020
346
return filteredCalendarInfo;
Aug 14, 2019
Aug 14, 2019
347
};
Apr 6, 2020
Apr 6, 2020
348
void add(const PropFind::CalendarInfo &infos)
Aug 14, 2019
Aug 14, 2019
349
350
351
352
353
354
{
paths.append(infos.remotePath);
enabled.append(infos.remotePath);
displayNames.append(infos.displayName);
colors.append(infos.color);
};
Apr 6, 2020
Apr 6, 2020
355
bool update(const PropFind::CalendarInfo &infos, bool &modified)
Aug 14, 2019
Aug 14, 2019
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
{
int i = paths.indexOf(infos.remotePath);
if (i < 0) {
return false;
}
if (displayNames[i] != infos.displayName || colors[i] != infos.color) {
displayNames[i] = infos.displayName;
colors[i] = infos.color;
modified = true;
}
return true;
};
bool remove(const QString &path)
{
int at = paths.indexOf(path);
if (at >= 0) {
paths.removeAt(at);
enabled.removeAll(path);
displayNames.removeAt(at);
colors.removeAt(at);
}
return (at >= 0);
}
void store(Accounts::Account *account, const Accounts::Service &srv)
{
account->selectService(srv);
account->setValue("calendars", paths);
account->setValue("enabled_calendars", enabled);
account->setValue("calendar_display_names", displayNames);
account->setValue("calendar_colors", colors);
account->selectService(Accounts::Service());
account->syncAndBlock();
};
private:
QStringList paths;
QStringList displayNames;
QStringList colors;
QStringList enabled;
};
Apr 6, 2020
Apr 6, 2020
396
QList<PropFind::CalendarInfo> CalDavClient::loadAccountCalendars() const
Apr 3, 2014
Apr 3, 2014
397
{
Apr 6, 2020
Apr 6, 2020
398
Accounts::Service srv;
Apr 7, 2020
Apr 7, 2020
399
Accounts::Account *account = getAccountForCalendars(&srv);
Apr 6, 2020
Apr 6, 2020
400
401
if (!account) {
return QList<PropFind::CalendarInfo>();
Apr 3, 2014
Apr 3, 2014
402
}
Aug 14, 2019
Aug 14, 2019
403
struct CalendarSettings calendarSettings(account);
Apr 3, 2014
Apr 3, 2014
404
405
account->selectService(Accounts::Service());
Apr 6, 2020
Apr 6, 2020
406
return calendarSettings.enabledCalendars(calendarSettings.toCalendars());
Apr 3, 2014
Apr 3, 2014
407
408
}
Apr 6, 2020
Apr 6, 2020
409
QList<PropFind::CalendarInfo> CalDavClient::mergeAccountCalendars(const QList<PropFind::CalendarInfo> &calendars) const
Aug 14, 2019
Aug 14, 2019
410
411
{
Accounts::Service srv;
Apr 7, 2020
Apr 7, 2020
412
Accounts::Account *account = getAccountForCalendars(&srv);
Aug 14, 2019
Aug 14, 2019
413
if (!account) {
Apr 6, 2020
Apr 6, 2020
414
return QList<PropFind::CalendarInfo>();
Aug 14, 2019
Aug 14, 2019
415
}
Aug 14, 2019
Aug 14, 2019
416
struct CalendarSettings calendarSettings(account);
Aug 14, 2019
Aug 14, 2019
417
418
419
account->selectService(Accounts::Service());
bool modified = false;
Apr 6, 2020
Apr 6, 2020
420
for (QList<PropFind::CalendarInfo>::ConstIterator it = calendars.constBegin();
Aug 14, 2019
Aug 14, 2019
421
it != calendars.constEnd(); ++it) {
Aug 14, 2019
Aug 14, 2019
422
if (!calendarSettings.update(*it, modified)) {
Aug 18, 2021
Aug 18, 2021
423
qCDebug(lcCalDav) << "Found a new upstream calendar:" << it->remotePath << it->displayName;
Aug 14, 2019
Aug 14, 2019
424
calendarSettings.add(*it);
Aug 14, 2019
Aug 14, 2019
425
426
modified = true;
} else {
Aug 18, 2021
Aug 18, 2021
427
qCDebug(lcCalDav) << "Already existing calendar:" << it->remotePath << it->displayName << it->color;
Aug 14, 2019
Aug 14, 2019
428
429
430
}
}
if (modified) {
Aug 18, 2021
Aug 18, 2021
431
qCDebug(lcCalDav) << "Store modifications to calendar settings.";
Aug 14, 2019
Aug 14, 2019
432
calendarSettings.store(account, srv);
Aug 14, 2019
Aug 14, 2019
433
}
Apr 6, 2020
Apr 6, 2020
434
435
return calendarSettings.enabledCalendars(calendars);
Aug 14, 2019
Aug 14, 2019
436
437
}
Apr 6, 2020
Apr 6, 2020
438
void CalDavClient::removeAccountCalendars(const QStringList &paths)
Aug 14, 2019
Aug 14, 2019
439
440
{
Accounts::Service srv;
Apr 7, 2020
Apr 7, 2020
441
Accounts::Account *account = getAccountForCalendars(&srv);
Aug 14, 2019
Aug 14, 2019
442
443
444
if (!account) {
return;
}
Aug 14, 2019
Aug 14, 2019
445
struct CalendarSettings calendarSettings(account);
Aug 14, 2019
Aug 14, 2019
446
447
448
449
450
account->selectService(Accounts::Service());
bool modified = false;
for (QStringList::ConstIterator it = paths.constBegin();
it != paths.constEnd(); ++it) {
Aug 14, 2019
Aug 14, 2019
451
if (calendarSettings.remove(*it)) {
Aug 18, 2021
Aug 18, 2021
452
qCDebug(lcCalDav) << "Found a deleted upstream calendar:" << *it;
Aug 14, 2019
Aug 14, 2019
453
454
455
456
modified = true;
}
}
if (modified) {
Aug 14, 2019
Aug 14, 2019
457
calendarSettings.store(account, srv);
Aug 14, 2019
Aug 14, 2019
458
459
460
}
}
Feb 19, 2014
Feb 19, 2014
461
462
bool CalDavClient::initConfig()
{
Aug 18, 2021
Aug 18, 2021
463
464
FUNCTION_CALL_TRACE(lcCalDavTrace);
qCDebug(lcCalDav) << "Initiating config...";
465
Apr 3, 2014
Apr 3, 2014
466
467
468
if (!mManager) {
mManager = new Accounts::Manager(this);
}
Mar 3, 2014
Mar 3, 2014
469
470
471
472
473
QString accountIdString = iProfile.key(Buteo::KEY_ACCOUNT_ID);
bool accountIdOk = false;
int accountId = accountIdString.toInt(&accountIdOk);
if (!accountIdOk) {
Aug 18, 2021
Aug 18, 2021
474
qCWarning(lcCalDav) << "no account id specified," << Buteo::KEY_ACCOUNT_ID << "not found in profile";
475
476
return false;
}
Apr 1, 2015
Apr 1, 2015
477
mAccountId = accountId;
Aug 14, 2019
Aug 14, 2019
478
Jun 5, 2014
Jun 5, 2014
479
Accounts::Service srv;
Apr 7, 2020
Apr 7, 2020
480
Accounts::Account *account = getAccountForCalendars(&srv);
Aug 14, 2019
Aug 14, 2019
481
if (!account) {
Mar 3, 2014
Mar 3, 2014
482
return false;
483
}
Mar 3, 2014
Mar 3, 2014
484
Apr 3, 2014
Apr 3, 2014
485
486
mSettings.setServerAddress(account->value("server_address").toString());
if (mSettings.serverAddress().isEmpty()) {
Aug 18, 2021
Aug 18, 2021
487
qCWarning(lcCalDav) << "remote_address not found in service settings";
Apr 3, 2014
Apr 3, 2014
488
return false;
Feb 19, 2014
Feb 19, 2014
489
}
Apr 6, 2021
Apr 6, 2021
490
mSettings.setDavRootPath(account->value("webdav_path").toString());
Jul 16, 2015
Jul 16, 2015
491
492
mSettings.setIgnoreSSLErrors(account->value("ignore_ssl_errors").toBool());
account->selectService(Accounts::Service());
Mar 3, 2014
Mar 3, 2014
493
Jun 5, 2014
Jun 5, 2014
494
mAuth = new AuthHandler(mManager, accountId, srv.name());
Oct 18, 2013
Oct 18, 2013
495
if (!mAuth->init()) {
496
497
return false;
}
Oct 18, 2013
Oct 18, 2013
498
499
connect(mAuth, SIGNAL(success()), this, SLOT(start()));
connect(mAuth, SIGNAL(failed()), this, SLOT(authenticationError()));
500
Mar 3, 2014
Mar 3, 2014
501
mSettings.setAccountId(accountId);
502
503
504
505
506
507
508
mSyncDirection = iProfile.syncDirection();
mConflictResPolicy = iProfile.conflictResolutionPolicy();
return true;
}
Nov 5, 2019
Nov 5, 2019
509
510
void CalDavClient::syncFinished(Buteo::SyncResults::MinorCode minorErrorCode,
const QString &message)
Mar 3, 2014
Mar 3, 2014
511
{
Aug 18, 2021
Aug 18, 2021
512
FUNCTION_CALL_TRACE(lcCalDavTrace);
513
Apr 10, 2014
Apr 10, 2014
514
515
clearAgents();
Apr 4, 2014
Apr 4, 2014
516
517
518
519
520
if (mCalendar) {
mCalendar->close();
}
if (mStorage) {
mStorage->close();
Jun 19, 2017
Jun 19, 2017
521
mStorage.clear();
Apr 4, 2014
Apr 4, 2014
522
}
Mar 3, 2014
Mar 3, 2014
523
Oct 7, 2021
Oct 7, 2021
524
525
if (minorErrorCode == Buteo::SyncResults::NO_ERROR
|| minorErrorCode == Buteo::SyncResults::ITEM_FAILURES) {
Aug 18, 2021
Aug 18, 2021
526
qCDebug(lcCalDav) << "CalDAV sync succeeded!" << message;
Nov 5, 2019
Nov 5, 2019
527
mResults.setMajorCode(Buteo::SyncResults::SYNC_RESULT_SUCCESS);
Oct 7, 2021
Oct 7, 2021
528
mResults.setMinorCode(minorErrorCode);
Apr 2, 2014
Apr 2, 2014
529
emit success(getProfileName(), message);
Mar 4, 2014
Mar 4, 2014
530
} else {
Aug 18, 2021
Aug 18, 2021
531
qCWarning(lcCalDav) << "CalDAV sync failed:" << minorErrorCode << message;
Nov 5, 2019
Nov 5, 2019
532
533
534
535
mResults.setMajorCode(minorErrorCode == Buteo::SyncResults::ABORTED
? Buteo::SyncResults::SYNC_RESULT_CANCELLED
: Buteo::SyncResults::SYNC_RESULT_FAILED);
mResults.setMinorCode(minorErrorCode);
Sep 5, 2014
Sep 5, 2014
536
Nov 3, 2014
Nov 3, 2014
537
if (minorErrorCode == Buteo::SyncResults::AUTHENTICATION_FAILURE) {
Sep 5, 2014
Sep 5, 2014
538
539
540
setCredentialsNeedUpdate(mSettings.accountId());
}
Apr 2, 2014
Apr 2, 2014
541
emit error(getProfileName(), message, minorErrorCode);
542
543
544
}
}
Feb 19, 2014
Feb 19, 2014
545
546
void CalDavClient::authenticationError()
{
Nov 5, 2019
Nov 5, 2019
547
548
syncFinished(Buteo::SyncResults::AUTHENTICATION_FAILURE,
QLatin1String("Authentication failed"));
549
550
}
Feb 19, 2014
Feb 19, 2014
551
Buteo::SyncProfile::SyncDirection CalDavClient::syncDirection()
552
{
Aug 18, 2021
Aug 18, 2021
553
FUNCTION_CALL_TRACE(lcCalDavTrace);
554
555
556
return mSyncDirection;
}
Feb 19, 2014
Feb 19, 2014
557
Buteo::SyncProfile::ConflictResolutionPolicy CalDavClient::conflictResolutionPolicy()
558
{
Aug 18, 2021
Aug 18, 2021
559
FUNCTION_CALL_TRACE(lcCalDavTrace);
560
561
562
return mConflictResPolicy;
}
Feb 19, 2014
Feb 19, 2014
563
Buteo::SyncResults CalDavClient::getSyncResults() const
564
{
Aug 18, 2021
Aug 18, 2021
565
FUNCTION_CALL_TRACE(lcCalDavTrace);
566
567
568
569
return mResults;
}
Apr 24, 2014
Apr 24, 2014
570
571
572
void CalDavClient::getSyncDateRange(const QDateTime &sourceDate, QDateTime *fromDateTime, QDateTime *toDateTime)
{
if (!fromDateTime || !toDateTime) {
Aug 18, 2021
Aug 18, 2021
573
qCWarning(lcCalDav) << "fromDate or toDate is invalid";
Apr 24, 2014
Apr 24, 2014
574
575
return;
}
Sep 26, 2017
Sep 26, 2017
576
577
578
579
580
581
const Buteo::Profile* client = iProfile.clientProfile();
bool valid = (client != 0);
uint prevPeriod = (valid) ? client->key(SYNC_PREV_PERIOD_KEY).toUInt(&valid) : 0;
*fromDateTime = sourceDate.addMonths((valid) ? -int(qMin(prevPeriod, uint(120))) : -6);
uint nextPeriod = (valid) ? client->key(SYNC_NEXT_PERIOD_KEY).toUInt(&valid) : 0;
*toDateTime = sourceDate.addMonths((valid) ? int(qMin(nextPeriod, uint(120))) : 12);
Apr 24, 2014
Apr 24, 2014
582
583
}
Jun 5, 2014
Jun 5, 2014
584
void CalDavClient::start()
Feb 19, 2014
Feb 19, 2014
585
{
Aug 18, 2021
Aug 18, 2021
586
FUNCTION_CALL_TRACE(lcCalDavTrace);
Mar 3, 2014
Mar 3, 2014
587
Jun 5, 2014
Jun 5, 2014
588
589
590
if (!mAuth->username().isEmpty() && !mAuth->password().isEmpty()) {
mSettings.setUsername(mAuth->username());
mSettings.setPassword(mAuth->password());
Mar 4, 2014
Mar 4, 2014
591
}
Jun 5, 2014
Jun 5, 2014
592
mSettings.setAuthToken(mAuth->token());
Mar 3, 2014
Mar 3, 2014
593
Mar 9, 2020
Mar 9, 2020
594
595
596
597
598
599
600
601
// read the calendar user address set, to get their mailto href.
PropFind *userAddressSetRequest = new PropFind(mNAManager, &mSettings, this);
connect(userAddressSetRequest, &Request::finished, [this, userAddressSetRequest] {
const QString userPrincipal = userAddressSetRequest->userPrincipal();
userAddressSetRequest->deleteLater();
if (!userPrincipal.isEmpty()) {
// determine the mailto href for this user.
mSettings.setUserPrincipal(userPrincipal);
Apr 6, 2020
Apr 6, 2020
602
603
604
605
606
PropFind *userHrefsRequest = new PropFind(mNAManager, &mSettings, this);
connect(userHrefsRequest, &Request::finished, [this, userHrefsRequest] {
userHrefsRequest->deleteLater();
mSettings.setUserMailtoHref(userHrefsRequest->userMailtoHref());
listCalendars(userHrefsRequest->userHomeHref());
Mar 9, 2020
Mar 9, 2020
607
});
Apr 6, 2020
Apr 6, 2020
608
userHrefsRequest->listUserAddressSet(userPrincipal);
Mar 9, 2020
Mar 9, 2020
609
610
611
612
613
614
615
616
} else {
// just continue normal calendar sync.
listCalendars();
}
});
userAddressSetRequest->listCurrentUserPrincipal();
}
Apr 6, 2020
Apr 6, 2020
617
void CalDavClient::listCalendars(const QString &home)
Mar 9, 2020
Mar 9, 2020
618
{
Apr 6, 2020
Apr 6, 2020
619
620
QString remoteHome(home);
if (remoteHome.isEmpty()) {
Aug 18, 2021
Aug 18, 2021
621
qCWarning(lcCalDav) << "Cannot find the calendar root for this user, guess it from account.";
Apr 6, 2020
Apr 6, 2020
622
Accounts::Service srv;
Apr 7, 2020
Apr 7, 2020
623
Accounts::Account *account = getAccountForCalendars(&srv);
Apr 6, 2020
Apr 6, 2020
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
if (!account) {
syncFinished(Buteo::SyncResults::INTERNAL_ERROR,
QLatin1String("unable to find account for calendar detection"));
return;
}
struct CalendarSettings calendarSettings(account);
QList<PropFind::CalendarInfo> allCalendarInfo = calendarSettings.toCalendars();
if (allCalendarInfo.isEmpty()) {
syncFinished(Buteo::SyncResults::INTERNAL_ERROR,
QLatin1String("no calendar listed for detection"));
return;
}
// Hacky here, try to guess the root for calendars from known
// calendar paths, by removing one level.
int lastIndex = allCalendarInfo[0].remotePath.lastIndexOf('/', -2);
remoteHome = allCalendarInfo[0].remotePath.left(lastIndex + 1);
Aug 14, 2019
Aug 14, 2019
640
641
}
PropFind *calendarRequest = new PropFind(mNAManager, &mSettings, this);
Apr 6, 2020
Apr 6, 2020
642
643
connect(calendarRequest, &Request::finished, this, [this, calendarRequest] {
calendarRequest->deleteLater();
Oct 26, 2020
Oct 26, 2020
644
645
646
if (calendarRequest->errorCode() == Buteo::SyncResults::NO_ERROR
// Request silently ignores this QNetworkReply::NetworkError
&& calendarRequest->networkError() != QNetworkReply::ContentOperationNotPermittedError) {
Apr 6, 2020
Apr 6, 2020
647
648
syncCalendars(mergeAccountCalendars(calendarRequest->calendars()));
} else {
Aug 18, 2021
Aug 18, 2021
649
qCWarning(lcCalDav) << "Cannot list calendars, fallback to stored ones in account.";
Apr 6, 2020
Apr 6, 2020
650
651
652
syncCalendars(loadAccountCalendars());
}
});
Apr 6, 2020
Apr 6, 2020
653
calendarRequest->listCalendars(remoteHome);
Aug 14, 2019
Aug 14, 2019
654
655
}
Apr 6, 2020
Apr 6, 2020
656
void CalDavClient::syncCalendars(const QList<PropFind::CalendarInfo> &allCalendarInfo)
Aug 14, 2019
Aug 14, 2019
657
658
{
if (allCalendarInfo.isEmpty()) {
Nov 5, 2019
Nov 5, 2019
659
660
syncFinished(Buteo::SyncResults::NO_ERROR,
QLatin1String("No calendars for this account"));
Apr 3, 2014
Apr 3, 2014
661
662
return;
}
Dec 18, 2020
Dec 18, 2020
663
mCalendar = mKCal::ExtendedCalendar::Ptr(new mKCal::ExtendedCalendar(QTimeZone::utc()));
Apr 4, 2014
Apr 4, 2014
664
mStorage = mKCal::ExtendedCalendar::defaultStorage(mCalendar);
Jun 19, 2017
Jun 19, 2017
665
if (!mStorage || !mStorage->open()) {
Nov 5, 2019
Nov 5, 2019
666
667
syncFinished(Buteo::SyncResults::DATABASE_FAILURE,
QLatin1String("unable to open calendar storage"));
Apr 3, 2014
Apr 3, 2014
668
669
return;
}
Mar 3, 2021
Mar 3, 2021
670
mCalendar->setUpdateLastModifiedOnChange(false);
Apr 10, 2014
Apr 10, 2014
671
Oct 9, 2017
Oct 9, 2017
672
cleanSyncRequired(mAccountId);
May 7, 2015
May 7, 2015
673
Apr 24, 2014
Apr 24, 2014
674
675
QDateTime fromDateTime;
QDateTime toDateTime;
Oct 9, 2017
Oct 9, 2017
676
getSyncDateRange(QDateTime::currentDateTime().toUTC(), &fromDateTime, &toDateTime);
Jun 5, 2014
Jun 5, 2014
677
Apr 1, 2015
Apr 1, 2015
678
// for each calendar path we need to sync:
May 7, 2015
May 7, 2015
679
// - if it is mapped to a known notebook, we need to perform quick sync
Apr 1, 2015
Apr 1, 2015
680
// - if no known notebook exists for it, we need to create one and perform clean sync
Apr 6, 2020
Apr 6, 2020
681
for (const PropFind::CalendarInfo &calendarInfo : allCalendarInfo) {
May 7, 2015
May 7, 2015
682
// TODO: could use some unused field from Notebook to store "need clean sync" flag?
Oct 9, 2017
Oct 9, 2017
683
684
NotebookSyncAgent *agent = new NotebookSyncAgent
(mCalendar, mStorage, mNAManager, &mSettings,
Apr 6, 2020
Apr 6, 2020
685
calendarInfo.remotePath, calendarInfo.readOnly, this);
Apr 6, 2020
Apr 6, 2020
686
687
688
const QString &email = (calendarInfo.userPrincipal == mSettings.userPrincipal()
|| calendarInfo.userPrincipal.isEmpty())
? mSettings.userMailtoHref() : QString();
Oct 9, 2017
Oct 9, 2017
689
690
if (!agent->setNotebookFromInfo(calendarInfo.displayName,
calendarInfo.color,
Apr 6, 2020
Apr 6, 2020
691
email,
Jun 6, 2023
Jun 6, 2023
692
693
694
calendarInfo.allowEvents,
calendarInfo.allowTodos,
calendarInfo.allowJournals,
Oct 9, 2017
Oct 9, 2017
695
696
697
698
QString::number(mAccountId),
getPluginName(),
getProfileName())) {
syncFinished(Buteo::SyncResults::DATABASE_FAILURE,
Nov 5, 2019
Nov 5, 2019
699
QLatin1String("unable to load calendar storage"));
Oct 9, 2017
Oct 9, 2017
700
return;
Jun 5, 2014
Jun 5, 2014
701
}
Nov 5, 2019
Nov 5, 2019
702
703
connect(agent, &NotebookSyncAgent::finished,
this, &CalDavClient::notebookSyncFinished);
Oct 9, 2017
Oct 9, 2017
704
705
mNotebookSyncAgents.append(agent);
Nov 12, 2019
Nov 12, 2019
706
707
708
agent->startSync(fromDateTime, toDateTime,
mSyncDirection != Buteo::SyncProfile::SYNC_DIRECTION_FROM_REMOTE,
mSyncDirection != Buteo::SyncProfile::SYNC_DIRECTION_TO_REMOTE);
Apr 3, 2014
Apr 3, 2014
709
}
Apr 10, 2014
Apr 10, 2014
710
if (mNotebookSyncAgents.isEmpty()) {
Nov 5, 2019
Nov 5, 2019
711
712
syncFinished(Buteo::SyncResults::INTERNAL_ERROR,
QLatin1String("Could not add or find existing notebooks for this account"));
Apr 10, 2014
Apr 10, 2014
713
}
Apr 3, 2014
Apr 3, 2014
714
}
715
Apr 10, 2014
Apr 10, 2014
716
void CalDavClient::clearAgents()
Apr 3, 2014
Apr 3, 2014
717
{
Aug 18, 2021
Aug 18, 2021
718
FUNCTION_CALL_TRACE(lcCalDavTrace);
Mar 3, 2014
Mar 3, 2014
719
Apr 10, 2014
Apr 10, 2014
720
721
for (int i=0; i<mNotebookSyncAgents.count(); i++) {
mNotebookSyncAgents[i]->deleteLater();
722
}
Apr 10, 2014
Apr 10, 2014
723
mNotebookSyncAgents.clear();
Mar 4, 2014
Mar 4, 2014
724
725
}
Oct 8, 2020
Oct 8, 2020
726
void CalDavClient::notebookSyncFinished()
Mar 4, 2014
Mar 4, 2014
727
{
Aug 18, 2021
Aug 18, 2021
728
729
FUNCTION_CALL_TRACE(lcCalDavTrace);
qCInfo(lcCalDav) << "Notebook sync finished. Total agents:" << mNotebookSyncAgents.count();
Mar 4, 2014
Mar 4, 2014
730
Apr 11, 2014
Apr 11, 2014
731
NotebookSyncAgent *agent = qobject_cast<NotebookSyncAgent*>(sender());
Oct 8, 2020
Oct 8, 2020
732
733
734
if (!agent) {
syncFinished(Buteo::SyncResults::INTERNAL_ERROR,
QLatin1String("cannot get NotebookSyncAgent object"));
May 20, 2019
May 20, 2019
735
736
return;
}
Oct 8, 2020
Oct 8, 2020
737
agent->disconnect(this);
May 20, 2019
May 20, 2019
738
Apr 10, 2014
Apr 10, 2014
739
740
741
742
743
bool finished = true;
for (int i=0; i<mNotebookSyncAgents.count(); i++) {
if (!mNotebookSyncAgents[i]->isFinished()) {
finished = false;
break;
Apr 3, 2014
Apr 3, 2014
744
}
Mar 4, 2014
Mar 4, 2014
745
}
Nov 5, 2019
Nov 5, 2019
746
if (finished) {
Oct 7, 2021
Oct 7, 2021
747
bool hasFatalError = false;
Aug 31, 2020
Aug 31, 2020
748
bool hasDatabaseErrors = false;
Oct 8, 2020
Oct 8, 2020
749
bool hasDownloadErrors = false;
Oct 8, 2020
Oct 8, 2020
750
bool hasUploadErrors = false;
Aug 14, 2019
Aug 14, 2019
751
QStringList deletedNotebooks;
Apr 10, 2014
Apr 10, 2014
752
for (int i=0; i<mNotebookSyncAgents.count(); i++) {
Oct 7, 2021
Oct 7, 2021
753
hasFatalError = hasFatalError || !mNotebookSyncAgents[i]->isCompleted();
Oct 8, 2020
Oct 8, 2020
754
hasDownloadErrors = hasDownloadErrors || mNotebookSyncAgents[i]->hasDownloadErrors();
Oct 8, 2020
Oct 8, 2020
755
hasUploadErrors = hasUploadErrors || mNotebookSyncAgents[i]->hasUploadErrors();
Apr 10, 2014
Apr 10, 2014
756
if (!mNotebookSyncAgents[i]->applyRemoteChanges()) {
Aug 18, 2021
Aug 18, 2021
757
qCWarning(lcCalDav) << "Unable to write notebook changes for notebook at index:" << i;
Aug 31, 2020
Aug 31, 2020
758
hasDatabaseErrors = true;
Apr 3, 2014
Apr 3, 2014
759
}
Aug 14, 2019
Aug 14, 2019
760
761
if (mNotebookSyncAgents[i]->isDeleted()) {
deletedNotebooks += mNotebookSyncAgents[i]->path();
Oct 8, 2020
Oct 8, 2020
762
} else {
Nov 5, 2019
Nov 5, 2019
763
mResults.addTargetResults(mNotebookSyncAgents[i]->result());
Aug 14, 2019
Aug 14, 2019
764
}
May 20, 2019
May 20, 2019
765
mNotebookSyncAgents[i]->finalize();
Apr 3, 2014
Apr 3, 2014
766
}
Apr 6, 2020
Apr 6, 2020
767
removeAccountCalendars(deletedNotebooks);
Oct 7, 2021
Oct 7, 2021
768
if (hasFatalError) {
Oct 8, 2020
Oct 8, 2020
769
syncFinished(Buteo::SyncResults::CONNECTION_ERROR,
Oct 7, 2021
Oct 7, 2021
770
771
772
QLatin1String("unable to complete the sync process"));
} else if (hasDownloadErrors) {
syncFinished(Buteo::SyncResults::ITEM_FAILURES,
Oct 8, 2020
Oct 8, 2020
773
774
QLatin1String("unable to fetch all upstream changes"));
} else if (hasUploadErrors) {
Oct 7, 2021
Oct 7, 2021
775
syncFinished(Buteo::SyncResults::ITEM_FAILURES,
Oct 8, 2020
Oct 8, 2020
776
777
QLatin1String("unable to upsync all local changes"));
} else if (hasDatabaseErrors) {
Oct 7, 2021
Oct 7, 2021
778
syncFinished(Buteo::SyncResults::ITEM_FAILURES,
Oct 8, 2020
Oct 8, 2020
779
QLatin1String("unable to apply all remote changes"));
Aug 31, 2020
Aug 31, 2020
780
} else {
Aug 18, 2021
Aug 18, 2021
781
qCDebug(lcCalDav) << "Calendar storage saved successfully after writing notebook changes!";
Aug 31, 2020
Aug 31, 2020
782
783
syncFinished(Buteo::SyncResults::NO_ERROR);
}
Mar 4, 2014
Mar 4, 2014
784
}
785
}
Sep 5, 2014
Sep 5, 2014
786
787
788
789
790
void CalDavClient::setCredentialsNeedUpdate(int accountId)
{
Accounts::Account *account = mManager->account(accountId);
if (account) {
Nov 14, 2019
Nov 14, 2019
791
792
const Accounts::ServiceList services = account->services();
for (const Accounts::Service &currService : services) {
Sep 5, 2014
Sep 5, 2014
793
794
795
796
797
798
799
800
801
802
803
account->selectService(currService);
if (!account->value("calendars").toStringList().isEmpty()) {
account->setValue(QStringLiteral("CredentialsNeedUpdate"), QVariant::fromValue<bool>(true));
account->setValue(QStringLiteral("CredentialsNeedUpdateFrom"), QVariant::fromValue<QString>(QString::fromLatin1("caldav-sync")));
account->selectService(Accounts::Service());
account->syncAndBlock();
break;
}
}
}
}