00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
#include "freebusymanager.h"
00039
00040
#include "koprefs.h"
00041
#include "mailscheduler.h"
00042
00043
#include <libkcal/incidencebase.h>
00044
#include <libkcal/attendee.h>
00045
#include <libkcal/freebusy.h>
00046
#include <libkcal/journal.h>
00047
#include <libkcal/calendarlocal.h>
00048
#include <libkcal/icalformat.h>
00049
00050
#include <kio/job.h>
00051
#include <kdebug.h>
00052
#include <kmessagebox.h>
00053
#include <ktempfile.h>
00054
#include <kio/netaccess.h>
00055
#include <kapplication.h>
00056
#include <kconfig.h>
00057
#include <klocale.h>
00058
#include <kstandarddirs.h>
00059
00060
#include <qfile.h>
00061
#include <qbuffer.h>
00062
#include <qregexp.h>
00063
#include <qdir.h>
00064
00065
using namespace KCal;
00066
00067 FreeBusyDownloadJob::FreeBusyDownloadJob(
const QString &email,
const KURL &url,
00068 FreeBusyManager *manager,
00069
const char *name )
00070 :
QObject( manager, name ), mManager( manager ), mEmail( email )
00071 {
00072 KIO::Job *job = KIO::get( url,
false,
false );
00073 connect( job, SIGNAL( result( KIO::Job * ) ),
00074 SLOT( slotResult( KIO::Job * ) ) );
00075 connect( job, SIGNAL( data( KIO::Job *,
const QByteArray & ) ),
00076 SLOT( slotData( KIO::Job *,
const QByteArray & ) ) );
00077 }
00078
00079 FreeBusyDownloadJob::~FreeBusyDownloadJob()
00080 {
00081 }
00082
00083
00084
void FreeBusyDownloadJob::slotData( KIO::Job *,
const QByteArray &data )
00085 {
00086
QByteArray tmp = data;
00087 tmp.resize( tmp.size() + 1 );
00088 tmp[tmp.size()-1] = 0;
00089 mFreeBusyData += tmp;
00090 }
00091
00092
void FreeBusyDownloadJob::slotResult( KIO::Job *job )
00093 {
00094 kdDebug() <<
"FreeBusyDownloadJob::slotResult() " << mEmail << endl;
00095
00096
if( job->error() ) {
00097 kdDebug(5850) <<
"FreeBusyDownloadJob::slotResult() job error :-(" << endl;
00098 }
00099
00100 FreeBusy *fb = mManager->iCalToFreeBusy( mFreeBusyData );
00101 emit freeBusyDownloaded( fb, mEmail );
00102
00103
00104
delete this;
00105 }
00106
00107
00108 FreeBusyManager::FreeBusyManager(
QObject *parent,
const char *name )
00109 :
QObject( parent, name ),
00110 mCalendar( 0 ), mTimerID( 0 ), mUploadingFreeBusy( false )
00111 {
00112 }
00113
00114
void FreeBusyManager::setCalendar( KCal::Calendar *c )
00115 {
00116 mCalendar = c;
00117
if ( mCalendar ) {
00118 mFormat.setTimeZone( mCalendar->timeZoneId(),
true );
00119 }
00120 }
00121
00122 KCal::FreeBusy *FreeBusyManager::ownerFreeBusy()
00123 {
00124
QDateTime start = QDateTime::currentDateTime();
00125
QDateTime end = start.addDays( KOPrefs::instance()->mFreeBusyPublishDays );
00126
00127 FreeBusy *freebusy =
new FreeBusy( mCalendar, start, end );
00128 freebusy->setOrganizer( KOPrefs::instance()->email() );
00129
00130
return freebusy;
00131 }
00132
00133
QString FreeBusyManager::ownerFreeBusyAsString()
00134 {
00135 FreeBusy *freebusy = ownerFreeBusy();
00136
00137
QString result = freeBusyToIcal( freebusy );
00138
00139
delete freebusy;
00140
00141
return result;
00142 }
00143
00144
QString FreeBusyManager::freeBusyToIcal( KCal::FreeBusy *freebusy )
00145 {
00146
return mFormat.createScheduleMessage( freebusy, Scheduler::Publish );
00147 }
00148
00149
void FreeBusyManager::slotPerhapsUploadFB()
00150 {
00151
00152
if ( !KOPrefs::instance()->freeBusyPublishAuto() )
00153
return;
00154
if( mTimerID != 0 )
00155
00156
return;
00157
00158
int now = static_cast<int>( QDateTime::currentDateTime().toTime_t() );
00159
int eta = static_cast<int>( mNextUploadTime.toTime_t() ) - now;
00160
00161
if( !mUploadingFreeBusy ) {
00162
00163
if( mNextUploadTime.isNull() ||
00164 QDateTime::currentDateTime() > mNextUploadTime ) {
00165
00166 publishFreeBusy();
00167
return;
00168 }
00169
00170
00171
if( eta <= 0 ) {
00172
00173 publishFreeBusy();
00174
return;
00175 }
00176 }
else {
00177
00178
if( eta <= 0 ) {
00179 kdDebug(5850) <<
"This shouldn't happen! eta <= 0\n";
00180 eta = 10;
00181 }
00182 }
00183
00184
00185 mTimerID = startTimer( eta * 1000 );
00186
00187
if( mTimerID == 0 )
00188
00189 publishFreeBusy();
00190 }
00191
00192
00193
void FreeBusyManager::timerEvent(
QTimerEvent* )
00194 {
00195 publishFreeBusy();
00196 }
00197
00202
void FreeBusyManager::publishFreeBusy()
00203 {
00204
00205
if ( mUploadingFreeBusy )
00206
return;
00207 mUploadingFreeBusy =
true;
00208
00209
00210
if( mTimerID != 0 ) {
00211 killTimer( mTimerID );
00212 mTimerID = 0;
00213 }
00214
00215
00216 mNextUploadTime = QDateTime::currentDateTime();
00217
if( KOPrefs::instance()->mFreeBusyPublishDelay > 0 )
00218 mNextUploadTime = mNextUploadTime.addSecs(
00219 KOPrefs::instance()->mFreeBusyPublishDelay * 60 );
00220
00221
QString messageText = ownerFreeBusyAsString();
00222
00223
00224
00225 messageText = messageText.replace(
QRegExp(
"ORGANIZER\\s*:MAILTO:" ),
00226
"ORGANIZER:" );
00227
00228
00229 KTempFile tempFile;
00230
QTextStream *textStream = tempFile.textStream();
00231
if( textStream ) {
00232 *textStream << messageText;
00233 tempFile.close();
00234
00235
#if 0
00236
QString defaultEmail = KOCore()::self()->email();
00237
QString emailHost = defaultEmail.mid( defaultEmail.find(
'@' ) + 1 );
00238
00239
00240 KURL targetURL;
00241
if( KOPrefs::instance()->mPublishKolab ) {
00242
00243
QString server;
00244
if( KOPrefs::instance()->mPublishKolabServer ==
"%SERVER%" ||
00245 KOPrefs::instance()->mPublishKolabServer.isEmpty() )
00246 server = emailHost;
00247
else
00248 server = KOPrefs::instance()->mPublishKolabServer;
00249
00250 targetURL.setProtocol(
"webdavs" );
00251 targetURL.setHost( server );
00252
00253
QString fbname = KOPrefs::instance()->mPublishUserName;
00254
int at = fbname.find(
'@');
00255
if( at > 1 && fbname.length() > (uint)at ) {
00256 fbname = fbname.left(at);
00257 }
00258 targetURL.setPath(
"/freebusy/" + fbname +
".ifb" );
00259 targetURL.setUser( KOPrefs::instance()->mPublishUserName );
00260 targetURL.setPass( KOPrefs::instance()->mPublishPassword );
00261 }
else {
00262
00263 targetURL = KOPrefs::instance()->mPublishAnyURL.replace(
"%SERVER%",
00264 emailHost );
00265 targetURL.setUser( KOPrefs::instance()->mPublishUserName );
00266 targetURL.setPass( KOPrefs::instance()->mPublishPassword );
00267 }
00268
#endif
00269
00270 KURL targetURL ( KOPrefs::instance()->freeBusyPublishUrl() );
00271 targetURL.setUser( KOPrefs::instance()->mFreeBusyPublishUser );
00272 targetURL.setPass( KOPrefs::instance()->mFreeBusyPublishPassword );
00273
00274 KURL src;
00275 src.setPath( tempFile.name() );
00276
00277 kdDebug() <<
"FreeBusyManager::publishFreeBusy(): " << targetURL << endl;
00278
00279 KIO::Job * job = KIO::file_copy( src, targetURL, -1,
00280
true ,
00281
false ,
00282
false );
00283 connect( job, SIGNAL( result( KIO::Job * ) ),
00284 SLOT( slotUploadFreeBusyResult( KIO::Job * ) ) );
00285 }
00286 }
00287
00288
void FreeBusyManager::slotUploadFreeBusyResult(KIO::Job *_job)
00289 {
00290 KIO::FileCopyJob* job = static_cast<KIO::FileCopyJob *>(_job);
00291
if ( job->error() )
00292 KMessageBox::sorry( 0,
00293 i18n(
"<qt>The software could not upload your free/busy list to the "
00294
"URL '%1'. There might be a problem with the access rights, or "
00295
"you specified an incorrect URL. The system said: <em>%2</em>."
00296
"<br>Please check the URL or contact your system administrator."
00297
"</qt>" ).arg( job->destURL().prettyURL() )
00298 .arg( job->errorString() ) );
00299
00300 KURL src = job->srcURL();
00301 Q_ASSERT( src.isLocalFile() );
00302
if( src.isLocalFile() )
00303 QFile::remove(src.path());
00304 mUploadingFreeBusy =
false;
00305 }
00306
00307
bool FreeBusyManager::retrieveFreeBusy(
const QString &email )
00308 {
00309 kdDebug() <<
"FreeBusyManager::retrieveFreeBusy(): " << email << endl;
00310
00311
if( KOPrefs::instance()->thatIsMe( email ) ) {
00312
00313 kdDebug() <<
"freebusy of owner" << endl;
00314 emit freeBusyRetrieved( ownerFreeBusy(), email );
00315
return true;
00316 }
00317
00318
00319 KCal::FreeBusy *fb = loadFreeBusy( email );
00320
if ( fb ) {
00321 emit freeBusyRetrieved( fb, email );
00322 }
00323
00324
00325
if( !KOPrefs::instance()->mFreeBusyRetrieveAuto )
00326
return false;
00327
00328 mRetrieveQueue.append( email );
00329
00330
if ( mRetrieveQueue.count() > 1 )
return true;
00331
00332
return processRetrieveQueue();
00333 }
00334
00335
bool FreeBusyManager::processRetrieveQueue()
00336 {
00337
if ( mRetrieveQueue.isEmpty() )
return true;
00338
00339
QString email = mRetrieveQueue.first();
00340 mRetrieveQueue.pop_front();
00341
00342 KURL sourceURL = freeBusyUrl( email );
00343
00344 kdDebug() <<
"FreeBusyManager::retrieveFreeBusy(): url: " << sourceURL.url()
00345 << endl;
00346
00347
if ( !sourceURL.isValid() ) {
00348 kdDebug(5850) <<
"Invalid FB URL\n";
00349
return false;
00350 }
00351
00352
FreeBusyDownloadJob *job =
new FreeBusyDownloadJob( email, sourceURL,
this,
00353
"freebusy_download_job" );
00354 connect( job, SIGNAL( freeBusyDownloaded( KCal::FreeBusy *,
00355
const QString & ) ),
00356 SIGNAL( freeBusyRetrieved( KCal::FreeBusy *,
const QString & ) ) );
00357 connect( job, SIGNAL( freeBusyDownloaded( KCal::FreeBusy *,
00358
const QString & ) ),
00359 SLOT( processRetrieveQueue() ) );
00360
00361
return true;
00362 }
00363
00364
void FreeBusyManager::cancelRetrieval()
00365 {
00366 mRetrieveQueue.clear();
00367 }
00368
00369 KURL FreeBusyManager::freeBusyUrl(
const QString &email )
00370 {
00371
00372
QString configFile = locateLocal(
"data",
"korganizer/freebusyurls" );
00373 KConfig cfg( configFile );
00374
00375 cfg.setGroup( email );
00376
QString url = cfg.readEntry(
"url" );
00377
if ( !url.isEmpty() ) {
00378
return KURL( url );
00379 }
00380
00381
00382
if ( !KOPrefs::instance()->mFreeBusyRetrieveAuto )
00383
00384
return KURL();
00385
00386
00387
00388
int emailpos = email.find(
'@' );
00389
if( emailpos == -1 )
00390
return KURL();
00391
00392
00393
QString emailName = email.left( emailpos );
00394
00395
00396 KURL sourceURL;
00397 sourceURL = KOPrefs::instance()->mFreeBusyRetrieveUrl;
00398
00399
00400
if ( sourceURL.host() != email.mid( emailpos + 1 ) )
return KURL();
00401
00402
if ( KOPrefs::instance()->mFreeBusyFullDomainRetrieval )
00403 sourceURL.setFileName( email +
".ifb" );
00404
else
00405 sourceURL.setFileName( emailName +
".ifb" );
00406 sourceURL.setUser( KOPrefs::instance()->mFreeBusyRetrieveUser );
00407 sourceURL.setPass( KOPrefs::instance()->mFreeBusyRetrievePassword );
00408
00409
return sourceURL;
00410 }
00411
00412 KCal::FreeBusy *FreeBusyManager::iCalToFreeBusy(
const QCString &data )
00413 {
00414 kdDebug() <<
"FreeBusyManager::iCalToFreeBusy()" << endl;
00415
00416
QString freeBusyVCal = QString::fromUtf8( data );
00417 KCal::FreeBusy *fb = mFormat.parseFreeBusy( freeBusyVCal );
00418
if ( !fb ) {
00419 kdDebug() <<
"FreeBusyManager::iCalToFreeBusy(): Error parsing free/busy"
00420 << endl;
00421 }
else {
00422 saveFreeBusy( fb, fb->organizer() );
00423 }
00424
return fb;
00425 }
00426
00427
QString FreeBusyManager::freeBusyDir()
00428 {
00429
return locateLocal(
"data",
"korganizer/freebusy" );
00430 }
00431
00432 FreeBusy *FreeBusyManager::loadFreeBusy(
const QString &email )
00433 {
00434 kdDebug() <<
"FreeBusyManager::loadFreeBusy(): " << email << endl;
00435
00436
QString fbd = freeBusyDir();
00437
00438
QFile f( fbd +
"/" + email +
".ifb" );
00439
if ( !f.exists() ) {
00440 kdDebug() <<
"FreeBusyManager::loadFreeBusy() " << f.name()
00441 <<
" doesn't exist." << endl;
00442
return 0;
00443 }
00444
00445
if ( !f.open( IO_ReadOnly ) ) {
00446 kdDebug() <<
"FreeBusyManager::loadFreeBusy() Unable to open file "
00447 << f.name() << endl;
00448
return 0;
00449 }
00450
00451
QTextStream ts( &f );
00452
QString str = ts.read();
00453
00454
return iCalToFreeBusy( str.utf8() );
00455 }
00456
00457
bool FreeBusyManager::saveFreeBusy( FreeBusy *freebusy,
const QString &email )
00458 {
00459 kdDebug() <<
"FreeBusyManager::saveFreeBusy(): " << email << endl;
00460
00461
QString fbd = freeBusyDir();
00462
00463
QDir freeBusyDirectory( fbd );
00464
if ( !freeBusyDirectory.exists() ) {
00465 kdDebug() <<
"Directory " << fbd <<
" does not exist!" << endl;
00466 kdDebug() <<
"Creating directory: " << fbd << endl;
00467
00468
if( !freeBusyDirectory.mkdir( fbd,
true ) ) {
00469 kdDebug() <<
"Could not create directory: " << fbd << endl;
00470
return false;
00471 }
00472 }
00473
00474
QString filename( fbd );
00475 filename +=
"/";
00476 filename += email;
00477 filename +=
".ifb";
00478
QFile f( filename );
00479
00480 kdDebug() <<
"FreeBusyManager::saveFreeBusy(): filename: " << filename
00481 << endl;
00482
00483 freebusy->clearAttendees();
00484 freebusy->setOrganizer( email );
00485
00486
QString messageText = mFormat.createScheduleMessage( freebusy,
00487 Scheduler::Publish );
00488
00489
if ( !f.open( IO_ReadWrite ) ) {
00490 kdDebug() <<
"acceptFreeBusy: Can't open:" << filename <<
" for writing"
00491 << endl;
00492
return false;
00493 }
00494
QTextStream t( &f );
00495 t << messageText;
00496 f.close();
00497
00498
return true;
00499 }
00500
00501
#include "freebusymanager.moc"