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 )
113 mData.append( 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;
223 KUrl cachedUrl( 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();
243 if ( _job->error() ) {
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();
348 if ( !job->error() ) {
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 );
405 if ( job->error() ) {
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();
425 p->setEmail( email );
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 );
447 if ( job->error() ) {
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() ) {
522 if( mTimerID != 0 ) {
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 );
556 if ( mTimerID == 0 ) {
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 );
674 Q_UNUSED( errorText );
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 struct FreeBusyManagerStatic
729 FreeBusyManager instance;
734 K_GLOBAL_STATIC( FreeBusyManagerStatic, sManagerInstance )
736 FreeBusyManager::FreeBusyManager() : d_ptr( new FreeBusyManagerPrivate( this ) )
738 setObjectName( QLatin1String(
"FreeBusyManager" ) );
739 connect( CalendarSettings::self(), SIGNAL(configChanged()), SLOT(checkFreeBusyUrl()) );
742 FreeBusyManager::~FreeBusyManager()
747 FreeBusyManager *FreeBusyManager::self()
749 return &sManagerInstance->instance;
752 void FreeBusyManager::setCalendar(
const Akonadi::ETMCalendar::Ptr &c )
754 Q_D( FreeBusyManager );
756 if ( d->mCalendar ) {
757 disconnect( d->mCalendar.data(), SIGNAL(calendarChanged()) );
761 if ( d->mCalendar ) {
762 d->mFormat.setTimeSpec( d->mCalendar->timeSpec() );
763 connect( d->mCalendar.data(), SIGNAL(calendarChanged()), SLOT(uploadFreeBusy()) );
767 QTimer::singleShot( 0,
this, SLOT(uploadFreeBusy()) );
774 void FreeBusyManager::publishFreeBusy( QWidget *parentWidget )
776 Q_D( FreeBusyManager );
778 if ( d->mUploadingFreeBusy ) {
784 if ( !d->mCalendar ) {
788 KUrl targetURL( CalendarSettings::self()->freeBusyPublishUrl() );
789 if ( targetURL.isEmpty() ) {
792 i18n(
"<qt><p>No URL configured for uploading your free/busy list. "
793 "Please set it in KOrganizer's configuration dialog, on the "
794 "\"Free/Busy\" page.</p>"
795 "<p>Contact your system administrator for the exact URL and the "
796 "account details.</p></qt>" ),
797 i18n(
"No Free/Busy Upload URL" ) );
801 if ( d->mBrokenUrl ) {
805 if ( !targetURL.isValid() ) {
808 i18n(
"<qt>The target URL '%1' provided is invalid.</qt>", targetURL.prettyUrl() ),
809 i18n(
"Invalid URL" ) );
810 d->mBrokenUrl =
true;
813 targetURL.setUser( CalendarSettings::self()->freeBusyPublishUser() );
814 targetURL.setPass( CalendarSettings::self()->freeBusyPublishPassword() );
816 d->mUploadingFreeBusy =
true;
819 if ( d->mTimerID != 0 ) {
820 killTimer( d->mTimerID );
825 d->mNextUploadTime = QDateTime::currentDateTime();
826 if ( CalendarSettings::self()->freeBusyPublishDelay() > 0 ) {
828 d->mNextUploadTime.addSecs( CalendarSettings::self()->freeBusyPublishDelay() * 60 );
831 QString messageText = d->ownerFreeBusyAsString();
835 messageText = messageText.replace( QRegExp( QLatin1String(
"ORGANIZER\\s*:MAILTO:" ) ),
836 QLatin1String(
"ORGANIZER:" ) );
839 KTemporaryFile tempFile;
840 tempFile.setAutoRemove(
false );
841 if ( tempFile.open() ) {
842 QTextStream textStream ( &tempFile );
843 textStream << messageText;
847 QString defaultEmail = KOCore()::self()->email();
848 QString emailHost = defaultEmail.mid( defaultEmail.indexOf(
'@' ) + 1 );
852 if( CalendarSettings::self()->publishKolab() ) {
855 if ( CalendarSettings::self()->publishKolabServer() == QLatin1String(
"%SERVER%" ) ||
856 CalendarSettings::self()->publishKolabServer().isEmpty() ) {
859 server = CalendarSettings::self()->publishKolabServer();
862 targetURL.setProtocol(
"webdavs" );
863 targetURL.setHost( server );
865 QString fbname = CalendarSettings::self()->publishUserName();
866 int at = fbname.indexOf(
'@' );
867 if ( at > 1 && fbname.length() > (uint)at ) {
868 fbname = fbname.left(at);
870 targetURL.setPath(
"/freebusy/" + fbname +
".ifb" );
871 targetURL.setUser( CalendarSettings::self()->publishUserName() );
872 targetURL.setPass( CalendarSettings::self()->publishPassword() );
875 targetURL = CalendarSettings::self()->+publishAnyURL().replace(
"%SERVER%", emailHost );
876 targetURL.setUser( CalendarSettings::self()->publishUserName() );
877 targetURL.setPass( CalendarSettings::self()->publishPassword() );
882 src.setPath( tempFile.fileName() );
884 kDebug() << targetURL;
886 KIO::Job *job = KIO::file_copy( src, targetURL, -1, KIO::Overwrite | KIO::HideProgressInfo );
888 job->ui()->setWindow( parentWidget );
890 connect( job, SIGNAL(result(KJob*)), SLOT(slotUploadFreeBusyResult(KJob*)) );
894 void FreeBusyManager::mailFreeBusy(
int daysToPublish, QWidget *parentWidget )
896 Q_D( FreeBusyManager );
898 if ( !d->mCalendar ) {
902 KDateTime start = KDateTime::currentUtcDateTime().toTimeSpec( d->mCalendar->timeSpec() );
903 KDateTime end = start.addDays( daysToPublish );
905 KCalCore::Event::List events = d->mCalendar->rawEvents( start.date(), end.date() );
907 FreeBusy::Ptr freebusy(
new FreeBusy( events, start, end ) );
908 freebusy->setOrganizer( Person::Ptr(
909 new Person( Akonadi::CalendarUtils::fullName(),
910 Akonadi::CalendarUtils::email() ) ) );
912 QPointer<PublishDialog> publishdlg =
new PublishDialog();
913 if ( publishdlg->exec() == QDialog::Accepted ) {
915 MailScheduler *scheduler =
new MailScheduler();
916 connect( scheduler, SIGNAL(transactionFinished(Akonadi::Scheduler::Result,QString))
917 , d, SLOT(processMailSchedulerResult(Akonadi::Scheduler::Result,QString)) );
918 d->mParentWidgetForMailling = parentWidget;
920 scheduler->publish( freebusy, publishdlg->addresses() );
925 bool FreeBusyManager::retrieveFreeBusy(
const QString &email,
bool forceDownload,
926 QWidget *parentWidget )
928 Q_D( FreeBusyManager );
931 if ( email.isEmpty() ) {
932 kDebug() <<
"Email is empty";
936 d->mParentWidgetForRetrieval = parentWidget;
938 if ( Akonadi::CalendarUtils::thatIsMe( email ) ) {
940 kDebug() <<
"freebusy of owner, not downloading";
941 emit freeBusyRetrieved( d->ownerFreeBusy(), email );
946 KCalCore::FreeBusy::Ptr fb = loadFreeBusy( email );
948 kDebug() <<
"Found a cached copy for " << email;
949 emit freeBusyRetrieved( fb, email );
954 if ( !CalendarSettings::self()->freeBusyRetrieveAuto() && !forceDownload ) {
955 kDebug() <<
"Not downloading freebusy";
959 d->mRetrieveQueue.append( email );
961 if ( d->mRetrieveQueue.count() > 1 ) {
963 kWarning() <<
"Returning true without emit, is this correct?";
969 QMetaObject::invokeMethod( d,
"processRetrieveQueue", Qt::QueuedConnection );
973 void FreeBusyManager::cancelRetrieval()
975 Q_D( FreeBusyManager );
976 d->mRetrieveQueue.clear();
979 KCalCore::FreeBusy::Ptr FreeBusyManager::loadFreeBusy(
const QString &email )
981 Q_D( FreeBusyManager );
982 const QString fbd = d->freeBusyDir();
984 QFile f( fbd + QLatin1Char(
'/' ) + email + QLatin1String(
".ifb" ) );
986 kDebug() << f.fileName() <<
"doesn't exist.";
987 return KCalCore::FreeBusy::Ptr();
990 if ( !f.open( QIODevice::ReadOnly ) ) {
991 kDebug() <<
"Unable to open file" << f.fileName();
992 return KCalCore::FreeBusy::Ptr();
995 QTextStream ts( &f );
996 QString str = ts.readAll();
998 return d->iCalToFreeBusy( str.toUtf8() );
1001 bool FreeBusyManager::saveFreeBusy(
const KCalCore::FreeBusy::Ptr &freebusy,
1002 const KCalCore::Person::Ptr &person )
1004 Q_D( FreeBusyManager );
1006 kDebug() << person->fullName();
1008 QString fbd = d->freeBusyDir();
1010 QDir freeBusyDirectory( fbd );
1011 if ( !freeBusyDirectory.exists() ) {
1012 kDebug() <<
"Directory" << fbd <<
" does not exist!";
1013 kDebug() <<
"Creating directory:" << fbd;
1015 if( !freeBusyDirectory.mkpath( fbd ) ) {
1016 kDebug() <<
"Could not create directory:" << fbd;
1021 QString filename( fbd );
1022 filename += QLatin1Char(
'/' );
1023 filename += person->email();
1024 filename += QLatin1String(
".ifb" );
1025 QFile f( filename );
1027 kDebug() <<
"filename:" << filename;
1029 freebusy->clearAttendees();
1030 freebusy->setOrganizer( person );
1032 QString messageText = d->mFormat.createScheduleMessage( freebusy, KCalCore::iTIPPublish );
1034 if ( !f.open( QIODevice::ReadWrite ) ) {
1035 kDebug() <<
"acceptFreeBusy: Can't open:" << filename <<
"for writing";
1038 QTextStream t( &f );
1045 void FreeBusyManager::timerEvent( QTimerEvent * )
1050 #include "freebusymanager.moc"
1051 #include "freebusymanager_p.moc"
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.