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>
39#include <KStandardDirs>
40#include <KTemporaryFile>
43#include <KIO/JobUiDelegate>
44#include <KIO/NetAccess>
45#include <KLocalizedString>
55using namespace KCalCore;
59KUrl 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);
84FbCheckerJob::FbCheckerJob(
const QList<KUrl> &urlsToCheck, QObject *parent)
86 mUrlsToCheck(urlsToCheck)
90void FbCheckerJob::start()
95void 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*)));
111void FbCheckerJob::dataReceived(KIO::Job*,
const QByteArray &data)
116void 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();
128KUrl 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"));
148FreeBusyManagerPrivate::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));
175FreeBusyManagerPrivate::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));
186FreeBusyManagerPrivate::FreeBusyManagerPrivate(FreeBusyManager *q)
190 mUploadingFreeBusy(false),
192 mParentWidgetForRetrieval(0)
194 connect(
this, SIGNAL(freeBusyUrlRetrieved(QString,KUrl)),
195 SLOT(finishProcessRetrieveQueue(QString,KUrl)));
198QString FreeBusyManagerPrivate::freeBusyDir()
const
200 return KStandardDirs::locateLocal(
"data", QLatin1String(
"korganizer/freebusy"));
203void FreeBusyManagerPrivate::checkFreeBusyUrl()
205 KUrl targetURL(CalendarSettings::self()->freeBusyPublishUrl());
206 mBrokenUrl = targetURL.isEmpty() || !targetURL.isValid();
209static QString configFile()
211 static QString file = KStandardDirs::locateLocal(
"data", QLatin1String(
"korganizer/freebusyurls"));
215void 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*)));
239void 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*)));
345void 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());
363QString FreeBusyManagerPrivate::freeBusyToIcal(
const KCalCore::FreeBusy::Ptr &freebusy)
365 return mFormat.createScheduleMessage(freebusy, KCalCore::iTIPPublish);
368KCalCore::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;
381KCalCore::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())));
394QString FreeBusyManagerPrivate::ownerFreeBusyAsString()
396 return freeBusyToIcal(ownerFreeBusy());
399void 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();
444void 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;
467void 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);
490void 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*)));
512void 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();
562QStringList FreeBusyManagerPrivate::getFreeBusyProviders()
const
564 QStringList providers;
567 if (agent.
type().
capabilities().contains(QLatin1String(
"FreeBusyProvider"))) {
574void 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;
593void 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);
605void 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;
651void 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();
668void 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);
727class FreeBusyManagerStatic
730 FreeBusyManager instance;
735K_GLOBAL_STATIC(FreeBusyManagerStatic, sManagerInstance)
737FreeBusyManager::FreeBusyManager() : d_ptr(new FreeBusyManagerPrivate(this))
739 setObjectName(QLatin1String(
"FreeBusyManager"));
740 connect(CalendarSettings::self(), SIGNAL(configChanged()), SLOT(checkFreeBusyUrl()));
743FreeBusyManager::~FreeBusyManager()
748FreeBusyManager *FreeBusyManager::self()
750 return &sManagerInstance->instance;
753void 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()));
775void 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);
896void FreeBusyManager::mailFreeBusy(
int daysToPublish, QWidget *parentWidget)
898 Q_D(FreeBusyManager);
904 KDateTime start = KDateTime::currentUtcDateTime().toTimeSpec(d->mCalendar->timeSpec());
905 KDateTime end = start.addDays(daysToPublish);
907 KCalCore::Event::List events = d->mCalendar->rawEvents(start.date(), end.date());
909 FreeBusy::Ptr freebusy(
new FreeBusy(events, start, end));
910 freebusy->setOrganizer(Person::Ptr(
911 new Person(Akonadi::CalendarUtils::fullName(),
912 Akonadi::CalendarUtils::email())));
914 QPointer<PublishDialog> publishdlg =
new PublishDialog();
915 if (publishdlg->exec() == QDialog::Accepted) {
917 MailScheduler *scheduler =
new MailScheduler();
918 connect(scheduler, SIGNAL(transactionFinished(Akonadi::Scheduler::Result,QString))
919 , d, SLOT(processMailSchedulerResult(Akonadi::Scheduler::Result,QString)));
920 d->mParentWidgetForMailling = parentWidget;
922 scheduler->publish(freebusy, publishdlg->addresses());
927bool FreeBusyManager::retrieveFreeBusy(
const QString &email,
bool forceDownload,
928 QWidget *parentWidget)
930 Q_D(FreeBusyManager);
933 if (email.isEmpty()) {
934 kDebug() <<
"Email is empty";
938 d->mParentWidgetForRetrieval = parentWidget;
940 if (Akonadi::CalendarUtils::thatIsMe(email)) {
942 kDebug() <<
"freebusy of owner, not downloading";
943 emit freeBusyRetrieved(d->ownerFreeBusy(), email);
948 KCalCore::FreeBusy::Ptr fb = loadFreeBusy(email);
950 kDebug() <<
"Found a cached copy for " << email;
951 emit freeBusyRetrieved(fb, email);
956 if (!CalendarSettings::self()->freeBusyRetrieveAuto() && !forceDownload) {
957 kDebug() <<
"Not downloading freebusy";
961 d->mRetrieveQueue.append(email);
963 if (d->mRetrieveQueue.count() > 1) {
965 kWarning() <<
"Returning true without emit, is this correct?";
971 QMetaObject::invokeMethod(d,
"processRetrieveQueue", Qt::QueuedConnection);
975void FreeBusyManager::cancelRetrieval()
977 Q_D(FreeBusyManager);
978 d->mRetrieveQueue.clear();
981KCalCore::FreeBusy::Ptr FreeBusyManager::loadFreeBusy(
const QString &email)
983 Q_D(FreeBusyManager);
984 const QString fbd = d->freeBusyDir();
986 QFile f(fbd + QLatin1Char(
'/') + email + QLatin1String(
".ifb"));
988 kDebug() << f.fileName() <<
"doesn't exist.";
989 return KCalCore::FreeBusy::Ptr();
992 if (!f.open(QIODevice::ReadOnly)) {
993 kDebug() <<
"Unable to open file" << f.fileName();
994 return KCalCore::FreeBusy::Ptr();
998 QString str = ts.readAll();
1000 return d->iCalToFreeBusy(str.toUtf8());
1003bool FreeBusyManager::saveFreeBusy(
const KCalCore::FreeBusy::Ptr &freebusy,
1004 const KCalCore::Person::Ptr &person)
1006 Q_D(FreeBusyManager);
1008 kDebug() << person->fullName();
1010 QString fbd = d->freeBusyDir();
1012 QDir freeBusyDirectory(fbd);
1013 if (!freeBusyDirectory.exists()) {
1014 kDebug() <<
"Directory" << fbd <<
" does not exist!";
1015 kDebug() <<
"Creating directory:" << fbd;
1017 if (!freeBusyDirectory.mkpath(fbd)) {
1018 kDebug() <<
"Could not create directory:" << fbd;
1023 QString filename(fbd);
1024 filename += QLatin1Char(
'/');
1025 filename += person->email();
1026 filename += QLatin1String(
".ifb");
1029 kDebug() <<
"filename:" << filename;
1031 freebusy->clearAttendees();
1032 freebusy->setOrganizer(person);
1034 QString messageText = d->mFormat.createScheduleMessage(freebusy, KCalCore::iTIPPublish);
1036 if (!f.open(QIODevice::ReadWrite)) {
1037 kDebug() <<
"acceptFreeBusy: Can't open:" << filename <<
"for writing";
1047void FreeBusyManager::timerEvent(QTimerEvent *)
1052#include "moc_freebusymanager.cpp"
1053#include "moc_freebusymanager_p.cpp"
A representation of an agent instance.
QString identifier() const
Returns the unique identifier of the agent instance.
AgentType type() const
Returns the agent type of this instance.
QList< AgentInstance > List
Describes a list of agent instances.
static AgentManager * self()
Returns the global instance of the agent manager.
AgentInstance::List instances() const
Returns the list of all available agent instances.
QStringList capabilities() const
Returns the list of supported capabilities of the agent type.
void start()
Jobs are started automatically once entering the event loop again, no need to explicitly call this.
FreeBusyManager::Singleton.
FreeBusyProviderRequest(const QString &provider)
FreeBusyManagerPrivate::FreeBusyProviderRequest.