21 #include "freebusymanager.h"
22 #include "freebusymanager_p.h"
23 #include "freebusydownloadjob_p.h"
24 #include "mailscheduler_p.h"
25 #include "publishdialog.h"
26 #include "calendarsettings.h"
29 #include <akonadi/agentinstance.h>
30 #include <akonadi/agentmanager.h>
31 #include <akonadi/contact/contactsearchjob.h>
33 #include <kcalcore/event.h>
34 #include <kcalcore/freebusy.h>
35 #include <kcalcore/person.h>
38 #include <KMessageBox>
39 #include <KStandardDirs>
40 #include <KTemporaryFile>
43 #include <KIO/JobUiDelegate>
44 #include <KIO/NetAccess>
45 #include <KLocalizedString>
50 #include <QTextStream>
52 #include <QTimerEvent>
54 using namespace Akonadi;
55 using namespace KCalCore;
59 KUrl replaceVariablesUrl(
const KUrl &url,
const QString &email)
64 const int atPos = email.indexOf(
'@');
66 emailName = email.left(atPos);
67 emailHost = email.mid(atPos + 1);
70 QString saveStr = url.path();
71 saveStr.replace(QRegExp(
"%[Ee][Mm][Aa][Ii][Ll]%"), email);
72 saveStr.replace(QRegExp(
"%[Nn][Aa][Mm][Ee]%"), emailName);
73 saveStr.replace(QRegExp(
"%[Ss][Ee][Rr][Vv][Ee][Rr]%"), emailHost);
76 retUrl.setPath(saveStr);
84 FbCheckerJob::FbCheckerJob(
const QList<KUrl> &urlsToCheck, QObject *parent)
86 mUrlsToCheck(urlsToCheck)
90 void FbCheckerJob::start()
95 void FbCheckerJob::checkNextUrl()
97 if (mUrlsToCheck.isEmpty()) {
98 kDebug() <<
"No fb file found";
99 setError(KJob::UserDefinedError);
103 const KUrl url = mUrlsToCheck.takeFirst();
106 KIO::TransferJob *job = KIO::get(url, KIO::NoReload, KIO::HideProgressInfo);
107 connect(job, SIGNAL(data(KIO::Job*,QByteArray)),
this, SLOT(dataReceived(KIO::Job*,QByteArray)));
108 connect(job, SIGNAL(result(KJob*)),
this, SLOT(onGetJobFinished(KJob*)));
111 void FbCheckerJob::dataReceived(KIO::Job*,
const QByteArray &data)
116 void FbCheckerJob::onGetJobFinished(KJob *job)
118 KIO::TransferJob *transferJob =
static_cast<KIO::TransferJob*
>(job);
119 if (mData.contains(
"BEGIN:VCALENDAR")) {
120 kDebug() <<
"found freebusy";
121 mValidUrl = transferJob->url();
128 KUrl FbCheckerJob::validUrl()
const
137 : mRequestStatus(NotStarted), mInterface(0)
140 QSharedPointer<QDBusInterface>(
141 new QDBusInterface(
"org.freedesktop.Akonadi.Resource." + provider,
143 "org.freedesktop.Akonadi.Resource.FreeBusyProvider"));
148 FreeBusyManagerPrivate::FreeBusyProvidersRequestsQueue::FreeBusyProvidersRequestsQueue(
149 const QString &start,
const QString &end)
150 : mHandlersCount(0), mResultingFreeBusy(0)
152 KDateTime startDate, endDate;
154 if (!start.isEmpty()) {
156 startDate = KDateTime::fromString(start);
159 startDate = KDateTime(KDateTime::currentLocalDate());
160 mStartTime = startDate.toString();
163 if (!end.isEmpty()) {
165 endDate = KDateTime::fromString(end);
168 endDate = KDateTime(KDateTime::currentLocalDate()).addDays(14);
169 mEndTime = endDate.toString();
172 mResultingFreeBusy = KCalCore::FreeBusy::Ptr(
new KCalCore::FreeBusy(startDate, endDate));
175 FreeBusyManagerPrivate::FreeBusyProvidersRequestsQueue::FreeBusyProvidersRequestsQueue(
176 const KDateTime &start,
const KDateTime &end)
177 : mHandlersCount(0), mResultingFreeBusy(0)
179 mStartTime = start.toString();
180 mEndTime = end.toString();
181 mResultingFreeBusy = KCalCore::FreeBusy::Ptr(
new KCalCore::FreeBusy(start, end));
186 FreeBusyManagerPrivate::FreeBusyManagerPrivate(FreeBusyManager *q)
190 mUploadingFreeBusy(false),
192 mParentWidgetForRetrieval(0)
194 connect(
this, SIGNAL(freeBusyUrlRetrieved(QString,KUrl)),
195 SLOT(finishProcessRetrieveQueue(QString,KUrl)));
198 QString FreeBusyManagerPrivate::freeBusyDir()
const
200 return KStandardDirs::locateLocal(
"data", QLatin1String(
"korganizer/freebusy"));
203 void FreeBusyManagerPrivate::checkFreeBusyUrl()
205 KUrl targetURL(CalendarSettings::self()->freeBusyPublishUrl());
206 mBrokenUrl = targetURL.isEmpty() || !targetURL.isValid();
209 static QString configFile()
211 static QString file = KStandardDirs::locateLocal(
"data", QLatin1String(
"korganizer/freebusyurls"));
215 void FreeBusyManagerPrivate::fetchFreeBusyUrl(
const QString &email)
218 KConfig cfg(configFile());
219 KConfigGroup group = cfg.group(email);
220 QString url = group.readEntry(QLatin1String(
"url"));
221 if (!url.isEmpty()) {
222 kDebug() <<
"Found cached url:" << url;
224 if (Akonadi::CalendarUtils::thatIsMe(email)) {
225 cachedUrl.setUser(CalendarSettings::self()->freeBusyRetrieveUser());
226 cachedUrl.setPass(CalendarSettings::self()->freeBusyRetrievePassword());
228 emit freeBusyUrlRetrieved(email, replaceVariablesUrl(cachedUrl, email));
234 job->setProperty(
"contactEmail", QVariant::fromValue(email));
235 connect(job, SIGNAL(result(KJob*)),
this, SLOT(contactSearchJobFinished(KJob*)));
239 void FreeBusyManagerPrivate::contactSearchJobFinished(KJob *_job)
241 const QString email = _job->property(
"contactEmail").toString();
244 kError() <<
"Error while searching for contact: "
245 << _job->errorString() <<
", email = " << email;
246 emit freeBusyUrlRetrieved(email, KUrl());
251 KConfig cfg(configFile());
252 KConfigGroup group = cfg.group(email);
253 QString url = group.readEntry(QLatin1String(
"url"));
255 const KABC::Addressee::List contacts = job->
contacts();
256 foreach(
const KABC::Addressee &contact, contacts) {
257 const QString pref = contact.preferredEmail();
258 if (!pref.isEmpty() && pref != email) {
259 group = cfg.group(pref);
260 url = group.readEntry(
"url");
261 kDebug() <<
"Preferred email of" << email <<
"is" << pref;
262 if (!url.isEmpty()) {
263 kDebug() <<
"Taken url from preferred email:" << url;
264 emit freeBusyUrlRetrieved(email, replaceVariablesUrl(KUrl(url), email));
270 if (!CalendarSettings::self()->freeBusyRetrieveAuto()) {
272 kDebug() <<
"No automatic retrieving";
273 emit freeBusyUrlRetrieved(email, KUrl());
279 int emailpos = email.indexOf(QLatin1Char(
'@'));
280 if (emailpos == -1) {
281 kWarning() <<
"No '@' found in" << email;
282 emit freeBusyUrlRetrieved(email, KUrl());
286 const QString emailHost = email.mid(emailpos + 1);
289 if (CalendarSettings::self()->freeBusyCheckHostname()) {
292 const QString hostDomain = KUrl(CalendarSettings::self()->freeBusyRetrieveUrl()).host();
293 if (hostDomain != emailHost &&
294 !hostDomain.endsWith(QLatin1Char(
'.') + emailHost) &&
295 !emailHost.endsWith(QLatin1Char(
'.') + hostDomain)) {
297 kDebug() <<
"Host '" << hostDomain <<
"' doesn't match email '" << email <<
'\'';
298 emit freeBusyUrlRetrieved(email, KUrl());
303 if (CalendarSettings::self()->freeBusyRetrieveUrl().contains(QRegExp(
"\\.[xiv]fb$"))) {
306 const KUrl sourceUrl(CalendarSettings::self()->freeBusyRetrieveUrl());
307 KUrl fullpathURL = replaceVariablesUrl(sourceUrl, email);
310 fullpathURL.setUser(CalendarSettings::self()->freeBusyRetrieveUser());
311 fullpathURL.setPass(CalendarSettings::self()->freeBusyRetrievePassword());
315 kDebug() <<
"Found url. email=" << email <<
"; url=" << fullpathURL;
316 emit freeBusyUrlRetrieved(email, fullpathURL);
321 const QStringList extensions = QStringList() <<
"xfb" <<
"ifb" <<
"vfb";
322 QStringList::ConstIterator ext;
323 QList<KUrl> urlsToCheck;
324 for (ext = extensions.constBegin(); ext != extensions.constEnd(); ++ext) {
326 const KUrl sourceUrl = CalendarSettings::self()->freeBusyRetrieveUrl();
327 KUrl dirURL = replaceVariablesUrl(sourceUrl, email);
328 if (CalendarSettings::self()->freeBusyFullDomainRetrieval()) {
329 dirURL.addPath(email +
'.' + (*ext));
332 const QString emailName = email.left(emailpos);
333 dirURL.addPath(emailName +
'.' + (*ext));
335 dirURL.setUser(CalendarSettings::self()->freeBusyRetrieveUser());
336 dirURL.setPass(CalendarSettings::self()->freeBusyRetrievePassword());
337 urlsToCheck << dirURL;
339 KJob *checkerJob =
new FbCheckerJob(urlsToCheck,
this);
340 checkerJob->setProperty(
"email", email);
341 connect(checkerJob, SIGNAL(result(KJob*)),
this, SLOT(fbCheckerJobFinished(KJob*)));
345 void FreeBusyManagerPrivate::fbCheckerJobFinished(KJob *job)
347 const QString email = job->property(
"email").toString();
349 FbCheckerJob *checkerJob =
static_cast<FbCheckerJob*
>(job);
350 KUrl dirURL = checkerJob->validUrl();
352 KConfig cfg(configFile());
353 KConfigGroup group = cfg.group(email);
354 group.writeEntry(
"url", dirURL.prettyUrl());
355 kDebug() <<
"Found url email=" << email <<
"; url=" << dirURL;
356 emit freeBusyUrlRetrieved(email, dirURL);
358 kDebug() <<
"Returning invalid url";
359 emit freeBusyUrlRetrieved(email, KUrl());
363 QString FreeBusyManagerPrivate::freeBusyToIcal(
const KCalCore::FreeBusy::Ptr &freebusy)
365 return mFormat.createScheduleMessage(freebusy, KCalCore::iTIPPublish);
368 KCalCore::FreeBusy::Ptr FreeBusyManagerPrivate::iCalToFreeBusy(
const QByteArray &freeBusyData)
370 const QString freeBusyVCal(QString::fromUtf8(freeBusyData));
371 KCalCore::FreeBusy::Ptr fb = mFormat.parseFreeBusy(freeBusyVCal);
374 kDebug() <<
"Error parsing free/busy";
375 kDebug() << freeBusyVCal;
381 KCalCore::FreeBusy::Ptr FreeBusyManagerPrivate::ownerFreeBusy()
383 KDateTime start = KDateTime::currentUtcDateTime();
384 KDateTime end = start.addDays(CalendarSettings::self()->freeBusyPublishDays());
386 KCalCore::Event::List events = mCalendar ? mCalendar->rawEvents(start.date(), end.date()) : KCalCore::Event::List();
387 KCalCore::FreeBusy::Ptr freebusy(
new KCalCore::FreeBusy(events, start, end));
388 freebusy->setOrganizer(KCalCore::Person::Ptr(
389 new KCalCore::Person(Akonadi::CalendarUtils::fullName(),
390 Akonadi::CalendarUtils::email())));
394 QString FreeBusyManagerPrivate::ownerFreeBusyAsString()
396 return freeBusyToIcal(ownerFreeBusy());
399 void FreeBusyManagerPrivate::processFreeBusyDownloadResult(KJob *_job)
401 Q_Q(FreeBusyManager);
403 FreeBusyDownloadJob *job = qobject_cast<FreeBusyDownloadJob *>(_job);
406 kError() <<
"Error downloading freebusy" << _job->errorString();
408 mParentWidgetForRetrieval,
409 i18n(
"Failed to download free/busy data from: %1\nReason: %2",
410 job->url().prettyUrl(), job->errorText()),
411 i18n(
"Free/busy retrieval error"));
416 mFreeBusyUrlEmailMap.take(job->url());
418 KCalCore::FreeBusy::Ptr fb = iCalToFreeBusy(job->rawFreeBusyData());
420 Q_ASSERT(mFreeBusyUrlEmailMap.contains(job->url()));
421 const QString email = mFreeBusyUrlEmailMap.take(job->url());
424 KCalCore::Person::Ptr p = fb->organizer();
426 q->saveFreeBusy(fb, p);
427 kDebug() <<
"Freebusy retrieved for " << email;
428 emit q->freeBusyRetrieved(fb, email);
430 kError() <<
"Error downloading freebusy, invalid fb.";
432 mParentWidgetForRetrieval,
433 i18n(
"Failed to parse free/busy information that was retrieved from: %1",
434 job->url().prettyUrl()),
435 i18n(
"Free/busy retrieval error"));
441 processRetrieveQueue();
444 void FreeBusyManagerPrivate::processFreeBusyUploadResult(KJob *_job)
446 KIO::FileCopyJob *job =
static_cast<KIO::FileCopyJob *
>(_job);
450 i18n(
"<qt><p>The software could not upload your free/busy list to "
451 "the URL '%1'. There might be a problem with the access "
452 "rights, or you specified an incorrect URL. The system said: "
454 "<p>Please check the URL or contact your system administrator."
455 "</p></qt>", job->destUrl().prettyUrl(),
456 job->errorString()));
459 KUrl src = job->srcUrl();
460 Q_ASSERT(src.isLocalFile());
461 if (src.isLocalFile()) {
462 QFile::remove(src.toLocalFile());
464 mUploadingFreeBusy =
false;
467 void FreeBusyManagerPrivate::processRetrieveQueue()
469 if (mRetrieveQueue.isEmpty()) {
473 QString email = mRetrieveQueue.takeFirst();
476 QStringList providers = getFreeBusyProviders();
477 kDebug() <<
"Got the following FreeBusy providers: " << providers;
481 if (!providers.isEmpty()) {
482 queryFreeBusyProviders(providers, email);
484 fetchFreeBusyUrl(email);
490 void FreeBusyManagerPrivate::finishProcessRetrieveQueue(
const QString &email,
491 const KUrl &freeBusyUrlForEmail)
493 Q_Q(FreeBusyManager);
495 if (!freeBusyUrlForEmail.isValid()) {
496 kDebug() <<
"Invalid FreeBusy URL" << freeBusyUrlForEmail.prettyUrl() << email;
500 if (mFreeBusyUrlEmailMap.contains(freeBusyUrlForEmail)) {
501 kDebug() <<
"Download already in progress for " << freeBusyUrlForEmail;
505 mFreeBusyUrlEmailMap.insert(freeBusyUrlForEmail, email);
507 FreeBusyDownloadJob *job =
new FreeBusyDownloadJob(freeBusyUrlForEmail, mParentWidgetForRetrieval);
508 q->connect(job, SIGNAL(result(KJob*)), SLOT(processFreeBusyDownloadResult(KJob*)));
512 void FreeBusyManagerPrivate::uploadFreeBusy()
514 Q_Q(FreeBusyManager);
517 if (!CalendarSettings::self()->freeBusyPublishAuto() ||
518 CalendarSettings::self()->freeBusyPublishUrl().isEmpty()) {
527 int now =
static_cast<int>(QDateTime::currentDateTime().toTime_t());
528 int eta =
static_cast<int>(mNextUploadTime.toTime_t()) - now;
530 if (!mUploadingFreeBusy) {
532 if (mNextUploadTime.isNull() ||
533 QDateTime::currentDateTime() > mNextUploadTime) {
535 q->publishFreeBusy();
542 q->publishFreeBusy();
548 kDebug() <<
"This shouldn't happen! eta <= 0";
554 mTimerID = q->startTimer(eta * 1000);
558 q->publishFreeBusy();
562 QStringList FreeBusyManagerPrivate::getFreeBusyProviders()
const
564 QStringList providers;
567 if (agent.
type().
capabilities().contains(QLatin1String(
"FreeBusyProvider"))) {
574 void FreeBusyManagerPrivate::queryFreeBusyProviders(
const QStringList &providers,
575 const QString &email)
577 if (!mProvidersRequestsByEmail.contains(email)) {
578 mProvidersRequestsByEmail[email] = FreeBusyProvidersRequestsQueue();
581 foreach(
const QString &provider, providers) {
582 FreeBusyProviderRequest request(provider);
584 connect(request.mInterface.data(), SIGNAL(handlesFreeBusy(QString,
bool)),
585 this, SLOT(onHandlesFreeBusy(QString,
bool)));
587 request.mInterface->call(
"canHandleFreeBusy", email);
588 request.mRequestStatus = FreeBusyProviderRequest::HandlingRequested;
589 mProvidersRequestsByEmail[email].mRequests << request;
593 void FreeBusyManagerPrivate::queryFreeBusyProviders(
const QStringList &providers,
594 const QString &email,
595 const KDateTime &start,
596 const KDateTime &end)
598 if (!mProvidersRequestsByEmail.contains(email)) {
599 mProvidersRequestsByEmail[email] = FreeBusyProvidersRequestsQueue(start, end);
602 queryFreeBusyProviders(providers, email);
605 void FreeBusyManagerPrivate::onHandlesFreeBusy(
const QString &email,
bool handles)
607 if (!mProvidersRequestsByEmail.contains(email)) {
611 QDBusInterface *iface =
dynamic_cast<QDBusInterface*
>(sender());
616 FreeBusyProvidersRequestsQueue *queue = &mProvidersRequestsByEmail[email];
617 QString respondingService = iface->service();
618 kDebug() << respondingService <<
"responded to our FreeBusy request:" << handles;
619 int requestIndex = -1;
621 for (
int i = 0; i < queue->mRequests.size(); ++i) {
622 if (queue->mRequests.at(i).mInterface->service() == respondingService) {
627 if (requestIndex == -1) {
631 disconnect(iface, SIGNAL(handlesFreeBusy(QString,
bool)),
632 this, SLOT(onHandlesFreeBusy(QString,
bool)));
635 queue->mRequests.removeAt(requestIndex);
638 if (queue->mRequests.isEmpty() && queue->mHandlersCount == 0) {
639 mProvidersRequestsByEmail.remove(email);
640 fetchFreeBusyUrl(email);
643 ++queue->mHandlersCount;
644 connect(iface, SIGNAL(freeBusyRetrieved(QString,QString,
bool,QString)),
645 this, SLOT(onFreeBusyRetrieved(QString,QString,
bool,QString)));
646 iface->call(
"retrieveFreeBusy", email, queue->mStartTime, queue->mEndTime);
647 queue->mRequests[requestIndex].mRequestStatus = FreeBusyProviderRequest::FreeBusyRequested;
651 void FreeBusyManagerPrivate::processMailSchedulerResult(Akonadi::Scheduler::Result result,
652 const QString &errorMsg)
654 if (result == Scheduler::ResultSuccess) {
655 KMessageBox::information(
656 mParentWidgetForMailling,
657 i18n(
"The free/busy information was successfully sent."),
658 i18n(
"Sending Free/Busy"),
659 "FreeBusyPublishSuccess");
661 KMessageBox::error(mParentWidgetForMailling,
662 i18n(
"Unable to publish the free/busy data: %1", errorMsg));
665 sender()->deleteLater();
668 void FreeBusyManagerPrivate::onFreeBusyRetrieved(
const QString &email,
669 const QString &freeBusy,
671 const QString &errorText)
673 Q_Q(FreeBusyManager);
676 if (!mProvidersRequestsByEmail.contains(email)) {
680 QDBusInterface *iface =
dynamic_cast<QDBusInterface*
>(sender());
685 FreeBusyProvidersRequestsQueue *queue = &mProvidersRequestsByEmail[email];
686 QString respondingService = iface->service();
687 int requestIndex = -1;
689 for (
int i = 0; i < queue->mRequests.size(); ++i) {
690 if (queue->mRequests.at(i).mInterface->service() == respondingService) {
695 if (requestIndex == -1) {
699 disconnect(iface, SIGNAL(freeBusyRetrieved(QString,QString,
bool,QString)),
700 this, SLOT(onFreeBusyRetrieved(QString,QString,
bool,QString)));
702 queue->mRequests.removeAt(requestIndex);
705 KCalCore::FreeBusy::Ptr fb = iCalToFreeBusy(freeBusy.toUtf8());
707 --queue->mHandlersCount;
709 queue->mResultingFreeBusy->merge(fb);
713 if (queue->mRequests.isEmpty()) {
714 if (queue->mHandlersCount == 0) {
715 fetchFreeBusyUrl(email);
717 emit q->freeBusyRetrieved(queue->mResultingFreeBusy, email);
719 mProvidersRequestsByEmail.remove(email);
727 class FreeBusyManagerStatic
730 FreeBusyManager instance;
735 K_GLOBAL_STATIC(FreeBusyManagerStatic, sManagerInstance)
737 FreeBusyManager::FreeBusyManager() : d_ptr(new FreeBusyManagerPrivate(this))
739 setObjectName(QLatin1String(
"FreeBusyManager"));
740 connect(CalendarSettings::self(), SIGNAL(configChanged()), SLOT(checkFreeBusyUrl()));
743 FreeBusyManager::~FreeBusyManager()
748 FreeBusyManager *FreeBusyManager::self()
750 return &sManagerInstance->instance;
753 void FreeBusyManager::setCalendar(
const Akonadi::ETMCalendar::Ptr &c)
755 Q_D(FreeBusyManager);
758 disconnect(d->mCalendar.data(), SIGNAL(calendarChanged()));
763 d->mFormat.setTimeSpec(d->mCalendar->timeSpec());
764 connect(d->mCalendar.data(), SIGNAL(calendarChanged()), SLOT(uploadFreeBusy()));
768 QTimer::singleShot(0,
this, SLOT(uploadFreeBusy()));
775 void FreeBusyManager::publishFreeBusy(QWidget *parentWidget)
777 Q_D(FreeBusyManager);
779 if (d->mUploadingFreeBusy) {
789 KUrl targetURL(CalendarSettings::self()->freeBusyPublishUrl());
790 if (targetURL.isEmpty()) {
793 i18n(
"<qt><p>No URL configured for uploading your free/busy list. "
794 "Please set it in KOrganizer's configuration dialog, on the "
795 "\"Free/Busy\" page.</p>"
796 "<p>Contact your system administrator for the exact URL and the "
797 "account details.</p></qt>"),
798 i18n(
"No Free/Busy Upload URL"));
806 if (!targetURL.isValid()) {
809 i18n(
"<qt>The target URL '%1' provided is invalid.</qt>", targetURL.prettyUrl()),
810 i18n(
"Invalid URL"));
811 d->mBrokenUrl =
true;
814 targetURL.setUser(CalendarSettings::self()->freeBusyPublishUser());
815 targetURL.setPass(CalendarSettings::self()->freeBusyPublishPassword());
817 d->mUploadingFreeBusy =
true;
820 if (d->mTimerID != 0) {
821 killTimer(d->mTimerID);
826 d->mNextUploadTime = QDateTime::currentDateTime();
827 if (CalendarSettings::self()->freeBusyPublishDelay() > 0) {
829 d->mNextUploadTime.addSecs(CalendarSettings::self()->freeBusyPublishDelay() * 60);
832 QString messageText = d->ownerFreeBusyAsString();
836 messageText = messageText.replace(QRegExp(QLatin1String(
"ORGANIZER\\s*:MAILTO:")),
837 QLatin1String(
"ORGANIZER:"));
840 KTemporaryFile tempFile;
841 tempFile.setAutoRemove(
false);
842 if (tempFile.open()) {
843 QTextStream textStream(&tempFile);
844 textStream << messageText;
848 QString defaultEmail = KOCore()::self()->email();
849 QString emailHost = defaultEmail.mid(defaultEmail.indexOf(
'@') + 1);
853 if (CalendarSettings::self()->publishKolab()) {
856 if (CalendarSettings::self()->publishKolabServer() == QLatin1String(
"%SERVER%") ||
857 CalendarSettings::self()->publishKolabServer().isEmpty()) {
860 server = CalendarSettings::self()->publishKolabServer();
863 targetURL.setProtocol(
"webdavs");
864 targetURL.setHost(server);
866 QString fbname = CalendarSettings::self()->publishUserName();
867 int at = fbname.indexOf(
'@');
868 if (at > 1 && fbname.length() > (uint)at) {
869 fbname = fbname.left(at);
871 targetURL.setPath(
"/freebusy/" + fbname +
".ifb");
872 targetURL.setUser(CalendarSettings::self()->publishUserName());
873 targetURL.setPass(CalendarSettings::self()->publishPassword());
876 targetURL = CalendarSettings::self()->+publishAnyURL().replace(
"%SERVER%", emailHost);
877 targetURL.setUser(CalendarSettings::self()->publishUserName());
878 targetURL.setPass(CalendarSettings::self()->publishPassword());
883 src.setPath(tempFile.fileName());
885 kDebug() << targetURL;
887 KIO::Job *job = KIO::file_copy(src, targetURL, -1, KIO::Overwrite | KIO::HideProgressInfo);
889 job->ui()->setWindow(parentWidget);
891 connect(job, SIGNAL(result(KJob*)), SLOT(slotUploadFreeBusyResult(KJob*)));
895 void FreeBusyManager::mailFreeBusy(
int daysToPublish, QWidget *parentWidget)
897 Q_D(FreeBusyManager);
903 KDateTime start = KDateTime::currentUtcDateTime().toTimeSpec(d->mCalendar->timeSpec());
904 KDateTime end = start.addDays(daysToPublish);
906 KCalCore::Event::List events = d->mCalendar->rawEvents(start.date(), end.date());
908 FreeBusy::Ptr freebusy(
new FreeBusy(events, start, end));
909 freebusy->setOrganizer(Person::Ptr(
910 new Person(Akonadi::CalendarUtils::fullName(),
911 Akonadi::CalendarUtils::email())));
913 QPointer<PublishDialog> publishdlg =
new PublishDialog();
914 if (publishdlg->exec() == QDialog::Accepted) {
916 MailScheduler *scheduler =
new MailScheduler();
917 connect(scheduler, SIGNAL(transactionFinished(Akonadi::Scheduler::Result,QString))
918 , d, SLOT(processMailSchedulerResult(Akonadi::Scheduler::Result,QString)));
919 d->mParentWidgetForMailling = parentWidget;
921 scheduler->publish(freebusy, publishdlg->addresses());
926 bool FreeBusyManager::retrieveFreeBusy(
const QString &email,
bool forceDownload,
927 QWidget *parentWidget)
929 Q_D(FreeBusyManager);
932 if (email.isEmpty()) {
933 kDebug() <<
"Email is empty";
937 d->mParentWidgetForRetrieval = parentWidget;
939 if (Akonadi::CalendarUtils::thatIsMe(email)) {
941 kDebug() <<
"freebusy of owner, not downloading";
942 emit freeBusyRetrieved(d->ownerFreeBusy(), email);
947 KCalCore::FreeBusy::Ptr fb = loadFreeBusy(email);
949 kDebug() <<
"Found a cached copy for " << email;
950 emit freeBusyRetrieved(fb, email);
955 if (!CalendarSettings::self()->freeBusyRetrieveAuto() && !forceDownload) {
956 kDebug() <<
"Not downloading freebusy";
960 d->mRetrieveQueue.append(email);
962 if (d->mRetrieveQueue.count() > 1) {
964 kWarning() <<
"Returning true without emit, is this correct?";
970 QMetaObject::invokeMethod(d,
"processRetrieveQueue", Qt::QueuedConnection);
974 void FreeBusyManager::cancelRetrieval()
976 Q_D(FreeBusyManager);
977 d->mRetrieveQueue.clear();
980 KCalCore::FreeBusy::Ptr FreeBusyManager::loadFreeBusy(
const QString &email)
982 Q_D(FreeBusyManager);
983 const QString fbd = d->freeBusyDir();
985 QFile f(fbd + QLatin1Char(
'/') + email + QLatin1String(
".ifb"));
987 kDebug() << f.fileName() <<
"doesn't exist.";
988 return KCalCore::FreeBusy::Ptr();
991 if (!f.open(QIODevice::ReadOnly)) {
992 kDebug() <<
"Unable to open file" << f.fileName();
993 return KCalCore::FreeBusy::Ptr();
997 QString str = ts.readAll();
999 return d->iCalToFreeBusy(str.toUtf8());
1002 bool FreeBusyManager::saveFreeBusy(
const KCalCore::FreeBusy::Ptr &freebusy,
1003 const KCalCore::Person::Ptr &person)
1005 Q_D(FreeBusyManager);
1007 kDebug() << person->fullName();
1009 QString fbd = d->freeBusyDir();
1011 QDir freeBusyDirectory(fbd);
1012 if (!freeBusyDirectory.exists()) {
1013 kDebug() <<
"Directory" << fbd <<
" does not exist!";
1014 kDebug() <<
"Creating directory:" << fbd;
1016 if (!freeBusyDirectory.mkpath(fbd)) {
1017 kDebug() <<
"Could not create directory:" << fbd;
1022 QString filename(fbd);
1023 filename += QLatin1Char(
'/');
1024 filename += person->email();
1025 filename += QLatin1String(
".ifb");
1028 kDebug() <<
"filename:" << filename;
1030 freebusy->clearAttendees();
1031 freebusy->setOrganizer(person);
1033 QString messageText = d->mFormat.createScheduleMessage(freebusy, KCalCore::iTIPPublish);
1035 if (!f.open(QIODevice::ReadWrite)) {
1036 kDebug() <<
"acceptFreeBusy: Can't open:" << filename <<
"for writing";
1046 void FreeBusyManager::timerEvent(QTimerEvent *)
1051 #include "moc_freebusymanager.cpp"
1052 #include "moc_freebusymanager_p.cpp"
QList< AgentInstance > List
Describes a list of agent instances.
AgentInstance::List instances() const
Returns the list of all available agent instances.
AgentType type() const
Returns the agent type of this instance.
QString identifier() const
Returns the unique identifier of the agent instance.
void start()
Jobs are started automatically once entering the event loop again, no need to explicitly call this...
FreeBusyProviderRequest(const QString &provider)
FreeBusyManagerPrivate::FreeBusyProviderRequest.
QStringList capabilities() const
Returns the list of supported capabilities of the agent type.
static AgentManager * self()
Returns the global instance of the agent manager.
A representation of an agent instance.