korganizer

freebusymanager.cpp
1/*
2 This file is part of the Groupware/KOrganizer integration.
3
4 Requires the TQt and KDE widget libraries, available at no cost at
5 http://www.trolltech.com and http://www.kde.org respectively
6
7 Copyright (c) 2002-2004 Klarälvdalens Datakonsult AB
8 <info@klaralvdalens-datakonsult.se>
9 Copyright (c) 2004 Cornelius Schumacher <schumacher@kde.org>
10
11 This program is free software; you can redistribute it and/or modify
12 it under the terms of the GNU General Public License as published by
13 the Free Software Foundation; either version 2 of the License, or
14 (at your option) any later version.
15
16 This program is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 GNU General Public License for more details.
20
21 You should have received a copy of the GNU General Public License
22 along with this program; if not, write to the Free Software
23 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
24 MA 02110-1301, USA.
25
26 In addition, as a special exception, the copyright holders give
27 permission to link the code of this program with any edition of
28 the TQt library by Trolltech AS, Norway (or with modified versions
29 of TQt that use the same license as TQt), and distribute linked
30 combinations including the two. You must obey the GNU General
31 Public License in all respects for all of the code used other than
32 TQt. If you modify this file, you may extend this exception to
33 your version of the file, but you are not obligated to do so. If
34 you do not wish to do so, delete this exception statement from
35 your version.
36*/
37
38#include "freebusymanager.h"
39
40#include "koprefs.h"
41#include "mailscheduler.h"
42#include "actionmanager.h"
43#include "korganizer.h"
44
45#include <libkcal/incidencebase.h>
46#include <libkcal/attendee.h>
47#include <libkcal/freebusy.h>
48#include <libkcal/journal.h>
49#include <libkcal/calendarlocal.h>
50#include <libkcal/icalformat.h>
51
52#include <tdeio/job.h>
53#include <kdebug.h>
54#include <tdemessagebox.h>
55#include <tdetempfile.h>
56#include <tdeio/jobclasses.h>
57#include <tdeio/netaccess.h>
58#include <tdeio/scheduler.h>
59#include <tdeapplication.h>
60#include <tdeconfig.h>
61#include <tdelocale.h>
62#include <tdestandarddirs.h>
63#include <tdeabc/stdaddressbook.h>
64#include <tdeabc/addressee.h>
65
66#include <tqfile.h>
67#include <tqbuffer.h>
68#include <tqregexp.h>
69#include <tqdir.h>
70
71#define DEBUG_5850 kdDebug(5850)
72
73using namespace KCal;
74
75FreeBusyDownloadJob::FreeBusyDownloadJob( const TQString &email, const KURL &url,
76 FreeBusyManager *manager,
77 const char *name )
78 : TQObject( manager, name ), mManager( manager ), mEmail( email )
79{
80 TDEIO::TransferJob *job = TDEIO::get( url, false, false );
81 //pass the mainwindow to the job so any prompts are active
83 job->setWindow( korg->topLevelWidget() );
84
85 connect( job, TQ_SIGNAL( result( TDEIO::Job * ) ),
86 TQ_SLOT( slotResult( TDEIO::Job * ) ) );
87 connect( job, TQ_SIGNAL( data( TDEIO::Job *, const TQByteArray & ) ),
88 TQ_SLOT( slotData( TDEIO::Job *, const TQByteArray & ) ) );
89 TDEIO::Scheduler::scheduleJob( job );
90}
91
92FreeBusyDownloadJob::~FreeBusyDownloadJob()
93{
94}
95
96
97void FreeBusyDownloadJob::slotData( TDEIO::Job *, const TQByteArray &data )
98{
99 TQByteArray tmp = data;
100 tmp.resize( tmp.size() + 1 );
101 tmp[tmp.size()-1] = 0;
102 mFreeBusyData += tmp;
103}
104
105void FreeBusyDownloadJob::slotResult( TDEIO::Job *job )
106{
107 DEBUG_5850 << "FreeBusyDownloadJob::slotResult() " << mEmail << endl;
108
109 if( job->error() ) {
110 DEBUG_5850 << "FreeBusyDownloadJob::slotResult() job error for " << mEmail << endl;
111 emit freeBusyDownloadError( mEmail );
112 } else {
113 FreeBusy *fb = mManager->iCalToFreeBusy( mFreeBusyData );
114 if ( fb ) {
115 Person p = fb->organizer();
116 p.setEmail( mEmail );
117 mManager->saveFreeBusy( fb, p );
118 }
119 emit freeBusyDownloaded( fb, mEmail );
120 }
121 deleteLater();
122}
123
125
126FreeBusyManager::FreeBusyManager( TQObject *parent, const char *name )
127 : TQObject( parent, name ),
128 mCalendar( 0 ), mTimerID( 0 ), mUploadingFreeBusy( false ),
129 mBrokenUrl( false )
130{
131}
132
133void FreeBusyManager::setCalendar( KCal::Calendar *c )
134{
135 mCalendar = c;
136 if ( mCalendar ) {
137 mFormat.setTimeZone( mCalendar->timeZoneId(), true );
138 }
139}
140
141KCal::FreeBusy *FreeBusyManager::ownerFreeBusy()
142{
143 TQDateTime start = TQDateTime::currentDateTime();
144 TQDateTime end = start.addDays( KOPrefs::instance()->mFreeBusyPublishDays );
145
146 FreeBusy *freebusy = new FreeBusy( mCalendar, start, end );
147 freebusy->setOrganizer( Person( KOPrefs::instance()->fullName(),
148 KOPrefs::instance()->email() ) );
149
150 return freebusy;
151}
152
153TQString FreeBusyManager::ownerFreeBusyAsString()
154{
155 FreeBusy *freebusy = ownerFreeBusy();
156
157 TQString result = freeBusyToIcal( freebusy );
158
159 delete freebusy;
160
161 return result;
162}
163
164TQString FreeBusyManager::freeBusyToIcal( KCal::FreeBusy *freebusy )
165{
166 return mFormat.createScheduleMessage( freebusy, Scheduler::Publish );
167}
168
169void FreeBusyManager::slotPerhapsUploadFB()
170{
171 // user has automatic uploading disabled, bail out
172 if ( !KOPrefs::instance()->freeBusyPublishAuto() ||
173 KOPrefs::instance()->freeBusyPublishUrl().isEmpty() )
174 return;
175 if( mTimerID != 0 )
176 // A timer is already running, so we don't need to do anything
177 return;
178
179 int now = static_cast<int>( TQDateTime::currentDateTime().toTime_t() );
180 int eta = static_cast<int>( mNextUploadTime.toTime_t() ) - now;
181
182 if( !mUploadingFreeBusy ) {
183 // Not currently uploading
184 if( mNextUploadTime.isNull() ||
185 TQDateTime::currentDateTime() > mNextUploadTime ) {
186 // No uploading have been done in this session, or delay time is over
187 publishFreeBusy();
188 return;
189 }
190
191 // We're in the delay time and no timer is running. Start one
192 if( eta <= 0 ) {
193 // Sanity check failed - better do the upload
194 publishFreeBusy();
195 return;
196 }
197 } else {
198 // We are currently uploading the FB list. Start the timer
199 if( eta <= 0 ) {
200 DEBUG_5850 << "This shouldn't happen! eta <= 0\n";
201 eta = 10; // whatever
202 }
203 }
204
205 // Start the timer
206 mTimerID = startTimer( eta * 1000 );
207
208 if( mTimerID == 0 )
209 // startTimer failed - better do the upload
210 publishFreeBusy();
211}
212
213// This is used for delayed Free/Busy list uploading
214void FreeBusyManager::timerEvent( TQTimerEvent* )
215{
216 publishFreeBusy();
217}
218
219void FreeBusyManager::setBrokenUrl( bool isBroken )
220{
221 mBrokenUrl = isBroken;
222}
223
228void FreeBusyManager::publishFreeBusy()
229{
230 // Already uploading? Skip this one then.
231 if ( mUploadingFreeBusy )
232 return;
233 KURL targetURL( KOPrefs::instance()->freeBusyPublishUrl() );
234 if ( targetURL.isEmpty() ) {
235 KMessageBox::sorry( 0,
236 i18n( "<qt>No URL configured for uploading your free/busy list. Please "
237 "set it in KOrganizer's configuration dialog, on the \"Free/Busy\" page. "
238 "<br>Contact your system administrator for the exact URL and the "
239 "account details."
240 "</qt>" ), i18n("No Free/Busy Upload URL") );
241 return;
242 }
243 if ( mBrokenUrl ) // Url is invalid, don't try again
244 return;
245 if ( !targetURL.isValid() ) {
246 KMessageBox::sorry( 0,
247 i18n( "<qt>The target URL '%1' provided is invalid."
248 "</qt>" ).arg( targetURL.prettyURL() ), i18n("Invalid URL") );
249 mBrokenUrl = true;
250 return;
251 }
252
253// // Substitute %u and %d [FIXME]
254// TQString defaultEmail = KOCore()::self()->email();
255// int emailpos = defaultEmail.find( '@' );
256// if (emailpos != -1) {
257// const TQString emailName = defaultEmail.left( emailpos );
258// const TQString emailHost = defaultEmail.mid( emailpos + 1 );
259// targetURL = targetURL.url().replace("%25u", emailName, true);
260// targetURL = targetURL.url().replace("%25d", emailHost, true);
261// }
262 targetURL.setUser( KOPrefs::instance()->mFreeBusyPublishUser );
263 targetURL.setPass( KOPrefs::instance()->mFreeBusyPublishPassword );
264
265 mUploadingFreeBusy = true;
266
267 // If we have a timer running, it should be stopped now
268 if( mTimerID != 0 ) {
269 killTimer( mTimerID );
270 mTimerID = 0;
271 }
272
273 // Save the time of the next free/busy uploading
274 mNextUploadTime = TQDateTime::currentDateTime();
275 if( KOPrefs::instance()->mFreeBusyPublishDelay > 0 )
276 mNextUploadTime = mNextUploadTime.addSecs(
277 KOPrefs::instance()->mFreeBusyPublishDelay * 60 );
278
279 TQString messageText = ownerFreeBusyAsString();
280
281 // We need to massage the list a bit so that Outlook understands
282 // it.
283 messageText = messageText.replace( TQRegExp( "ORGANIZER\\s*:MAILTO:" ),
284 "ORGANIZER:" );
285
286 // Create a local temp file and save the message to it
287 KTempFile tempFile;
288 TQTextStream *textStream = tempFile.textStream();
289 if( textStream ) {
290 *textStream << messageText;
291 tempFile.close();
292
293#if 0
294 TQString defaultEmail = KOCore()::self()->email();
295 TQString emailHost = defaultEmail.mid( defaultEmail.find( '@' ) + 1 );
296
297 // Put target string together
298 KURL targetURL;
299 if( KOPrefs::instance()->mPublishKolab ) {
300 // we use Kolab
301 TQString server;
302 if( KOPrefs::instance()->mPublishKolabServer == "%SERVER%" ||
303 KOPrefs::instance()->mPublishKolabServer.isEmpty() )
304 server = emailHost;
305 else
306 server = KOPrefs::instance()->mPublishKolabServer;
307
308 targetURL.setProtocol( "webdavs" );
309 targetURL.setHost( server );
310
311 TQString fbname = KOPrefs::instance()->mPublishUserName;
312 int at = fbname.find('@');
313 if( at > 1 && fbname.length() > (uint)at ) {
314 fbname = fbname.left(at);
315 }
316 targetURL.setPath( "/freebusy/" + fbname + ".ifb" );
317 targetURL.setUser( KOPrefs::instance()->mPublishUserName );
318 targetURL.setPass( KOPrefs::instance()->mPublishPassword );
319 } else {
320 // we use something else
321 targetURL = KOPrefs::instance()->mPublishAnyURL.replace( "%SERVER%",
322 emailHost );
323 targetURL.setUser( KOPrefs::instance()->mPublishUserName );
324 targetURL.setPass( KOPrefs::instance()->mPublishPassword );
325 }
326#endif
327
328
329 KURL src;
330 src.setPath( tempFile.name() );
331
332 DEBUG_5850 << "FreeBusyManager::publishFreeBusy(): " << targetURL << endl;
333
334 TDEIO::Job * job = TDEIO::file_copy( src, targetURL, -1,
335 true /*overwrite*/,
336 false /*don't resume*/,
337 false /*don't show progress info*/ );
338 //pass the mainwindow to the job so any prompts are active
340 job->setWindow( korg->topLevelWidget() );
341
342 connect( job, TQ_SIGNAL( result( TDEIO::Job * ) ),
343 TQ_SLOT( slotUploadFreeBusyResult( TDEIO::Job * ) ) );
344 }
345}
346
347void FreeBusyManager::slotUploadFreeBusyResult(TDEIO::Job *_job)
348{
349 TDEIO::FileCopyJob* job = static_cast<TDEIO::FileCopyJob *>(_job);
350 if ( job->error() )
351 KMessageBox::sorry( 0,
352 i18n( "<qt>The software could not upload your free/busy list to the "
353 "URL '%1'. There might be a problem with the access rights, or "
354 "you specified an incorrect URL. The system said: <em>%2</em>."
355 "<br>Please check the URL or contact your system administrator."
356 "</qt>" ).arg( job->destURL().prettyURL() )
357 .arg( job->errorString() ) );
358 // Delete temp file
359 KURL src = job->srcURL();
360 Q_ASSERT( src.isLocalFile() );
361 if( src.isLocalFile() )
362 TQFile::remove(src.path());
363 mUploadingFreeBusy = false;
364}
365
366bool FreeBusyManager::retrieveFreeBusy( const TQString &email, bool forceDownload )
367{
368 DEBUG_5850 << "FreeBusyManager::retrieveFreeBusy(): " << email << endl;
369 if ( email.isEmpty() ) return false;
370
371 // Check for cached copy of free/busy list
372 KCal::FreeBusy *fb = loadFreeBusy( email );
373 if ( fb ) {
374 emit freeBusyRetrieved( fb, email );
375 }
376
377 // Don't download free/busy if the user does not want it.
378 if( !KOPrefs::instance()->mFreeBusyRetrieveAuto && !forceDownload) {
379 slotFreeBusyDownloadError( email ); // fblist
380 return false;
381 }
382
383 mRetrieveQueue.append( email );
384
385 if ( mRetrieveQueue.count() > 1 ) return true;
386
387 return processRetrieveQueue();
388}
389
390bool FreeBusyManager::processRetrieveQueue()
391{
392 if ( mRetrieveQueue.isEmpty() ) return true;
393
394 TQString email = mRetrieveQueue.first();
395 mRetrieveQueue.pop_front();
396
397 KURL sourceURL = freeBusyUrl( email );
398
399 kdDebug(5850) << "FreeBusyManager::processRetrieveQueue(): url: " << sourceURL << endl;
400
401 if ( !sourceURL.isValid() ) {
402 kdDebug(5850) << "Invalid FB URL\n";
403 slotFreeBusyDownloadError( email );
404 return false;
405 }
406
407 FreeBusyDownloadJob *job = new FreeBusyDownloadJob( email, sourceURL, this,
408 "freebusy_download_job" );
409 connect( job, TQ_SIGNAL( freeBusyDownloaded( KCal::FreeBusy *,
410 const TQString & ) ),
411 TQ_SIGNAL( freeBusyRetrieved( KCal::FreeBusy *, const TQString & ) ) );
412 connect( job, TQ_SIGNAL( freeBusyDownloaded( KCal::FreeBusy *,
413 const TQString & ) ),
414 TQ_SLOT( processRetrieveQueue() ) );
415
416 connect( job, TQ_SIGNAL( freeBusyDownloadError( const TQString& ) ),
417 this, TQ_SLOT( slotFreeBusyDownloadError( const TQString& ) ) );
418
419 return true;
420}
421
422void FreeBusyManager::slotFreeBusyDownloadError( const TQString& email )
423{
424 if( KOPrefs::instance()->thatIsMe( email ) ) {
425 // We tried to download our own free-busy list from the net, but it failed
426 // so use local version instead.
427 // The reason we try to download even our own free-busy list is that
428 // this allows to avoid showing as busy the folders that are "fb relevant for nobody"
429 // like shared resources (meeting rooms etc.)
430 DEBUG_5850 << "freebusy of owner, falling back to local list" << endl;
431 emit freeBusyRetrieved( ownerFreeBusy(), email );
432 }
433
434}
435
436void FreeBusyManager::cancelRetrieval()
437{
438 mRetrieveQueue.clear();
439}
440
441KURL replaceVariablesURL( const KURL &url, const TQString &email )
442{
443 TQString emailName, emailHost;
444 int emailpos = email.find( '@' );
445 if( emailpos >= 0 ) {
446 emailName = email.left( emailpos );
447 emailHost = email.mid( emailpos + 1 );
448 }
449
450 TQString saveStr = url.path();
451 saveStr.replace( TQRegExp( "%[Ee][Mm][Aa][Ii][Ll]%" ), email );
452 saveStr.replace( TQRegExp( "%[Nn][Aa][Mm][Ee]%" ), emailName );
453 saveStr.replace( TQRegExp( "%[Ss][Ee][Rr][Vv][Ee][Rr]%" ), emailHost );
454
455 KURL retUrl( url );
456 retUrl.setPath( saveStr );
457 return retUrl;
458}
459
460bool fbExists( const KURL &url )
461{
462 // We need this function because using TDEIO::NetAccess::exists()
463 // is useless for the http and https protocols. And getting back
464 // arbitrary data is also useless because a server can respond back
465 // with a "no such document" page. So we need smart checking.
466
467 TDEIO::Job *job = TDEIO::get( url, false, false );
468 TQByteArray data;
469 if ( TDEIO::NetAccess::synchronousRun( job, 0, &data ) ) {
470 TQString dataStr ( data );
471 if ( dataStr.contains( "BEGIN:VCALENDAR" ) ) {
472 return true;
473 }
474 }
475 return false;
476}
477
478KURL FreeBusyManager::freeBusyUrl( const TQString &email )
479{
480 DEBUG_5850 << "FreeBusyManager::freeBusyUrl(): " << email << endl;
481
482 // First check if there is a specific FB url for this email
483 TQString configFile = locateLocal( "data", "korganizer/freebusyurls" );
484 TDEConfig cfg( configFile );
485
486 cfg.setGroup( email );
487 TQString url = cfg.readEntry( "url" );
488 if ( !url.isEmpty() ) {
489 kdDebug(5850) << "found cached url: " << url << endl;
490 KURL cachedURL( url );
491 if ( KOPrefs::instance()->thatIsMe( email ) ) {
492 cachedURL.setUser( KOPrefs::instance()->mFreeBusyRetrieveUser );
493 cachedURL.setPass( KOPrefs::instance()->mFreeBusyRetrievePassword );
494 }
495 return replaceVariablesURL( cachedURL, email );
496 }
497
498 // Try with the url configurated by preferred email in kaddressbook
499 TDEABC::Addressee::List list= TDEABC::StdAddressBook::self( true )->findByEmail( email );
500 TDEABC::Addressee::List::Iterator it;
501 TQString pref;
502 for ( it = list.begin(); it != list.end(); ++it ) {
503 pref = (*it).preferredEmail();
504 if ( !pref.isEmpty() && pref != email ) {
505 kdDebug(5850) << "FreeBusyManager::freeBusyUrl():"
506 << "Preferred email of " << email << " is " << pref << endl;
507 cfg.setGroup( pref );
508 url = cfg.readEntry ( "url" );
509 if ( !url.isEmpty() ) {
510 kdDebug(5850) << "FreeBusyManager::freeBusyUrl():"
511 << "Taken url from preferred email:" << url << endl;
512 return replaceVariablesURL( KURL( url ), email );
513 }
514 }
515 }
516 // None found. Check if we do automatic FB retrieving then
517 if ( !KOPrefs::instance()->mFreeBusyRetrieveAuto ) {
518 kdDebug( 5850 ) << "no auto retrieving" << endl;
519 // No, so no FB list here
520 return KURL();
521 }
522
523 // Sanity check: Don't download if it's not a correct email
524 // address (this also avoids downloading for "(empty email)").
525 int emailpos = email.find( '@' );
526 if( emailpos == -1 ) {
527 return KURL();
528 }
529
530 // Cut off everything left of the @ sign to get the user name.
531 const TQString emailName = email.left( emailpos );
532 const TQString emailHost = email.mid( emailpos + 1 );
533
534 // Build the URL
535 KURL sourceURL;
536 sourceURL = KOPrefs::instance()->mFreeBusyRetrieveUrl;
537
538 if ( KOPrefs::instance()->mFreeBusyCheckHostname ) {
539 // Don't try to fetch free/busy data for users not on the specified servers
540 // This tests if the hostnames match, or one is a subset of the other
541 const TQString hostDomain = sourceURL.host();
542 if ( hostDomain != emailHost &&
543 !hostDomain.endsWith( '.' + emailHost ) &&
544 !emailHost.endsWith( '.' + hostDomain ) ) {
545 // Host names do not match
546 kdDebug(5850) << "Host '" << sourceURL.host() << "' doesn't match email '" << email << endl;
547 return KURL();
548 }
549 }
550
551 if ( sourceURL.url().contains( TQRegExp( "\\.[xiv]fb$" ) ) ) { // user specified a fullpath
552 // do variable string replacements to the URL (MS Outlook style)
553 KURL fullpathURL = replaceVariablesURL( sourceURL, email );
554
555 // This should work with anything thrown at it, not just Kolab
556 // Notice that Kolab URLs are just entered as the base address, e.g. http://server.com/mykolab/
557 // This means that if the trailing slash is not entered, we can treat this as a custom, non-Kolab URL!
558 // In that case, just pass it on through with substitution for %u and %d
559 // TODO: May want an explicit configuration option in kogroupwareprefspage.ui for this
560 if ((fullpathURL.url().endsWith("/", true) == false) || (fullpathURL.url().contains("%25u", true)) || (fullpathURL.url().contains("%25d", true))) {
561 // A generic URL, substitute %u and %d
562 fullpathURL = fullpathURL.url().replace("%25u", emailName, true);
563 fullpathURL = fullpathURL.url().replace("%25d", emailHost, true);
564 }
565 else {
566 // This is (probably) a Kolab URL!
567 }
568
569 // set the User and Password part of the URL
570 fullpathURL.setUser( KOPrefs::instance()->mFreeBusyRetrieveUser );
571 fullpathURL.setPass( KOPrefs::instance()->mFreeBusyRetrievePassword );
572
573 // no need to cache this URL as this is pretty fast to get from the config value.
574
575 // return the fullpath URL
576 return fullpathURL;
577 }
578
579 // else we search for a fb file in the specified URL with known possible extensions
580
581 TQStringList extensions;
582 extensions << "xfb" << "ifb" << "vfb";
583 TQStringList::ConstIterator ext;
584 for ( ext = extensions.constBegin(); ext != extensions.constEnd(); ++ext ) {
585 // build a url for this extension
586 sourceURL = KOPrefs::instance()->mFreeBusyRetrieveUrl;
587 KURL dirURL = replaceVariablesURL( sourceURL, email );
588 if ( KOPrefs::instance()->mFreeBusyFullDomainRetrieval ) {
589 dirURL.addPath( email + '.' + (*ext) );
590 } else {
591 dirURL.addPath( emailName + '.' + (*ext ) );
592 }
593 dirURL.setUser( KOPrefs::instance()->mFreeBusyRetrieveUser );
594 dirURL.setPass( KOPrefs::instance()->mFreeBusyRetrievePassword );
595 if ( fbExists( dirURL ) ) {
596 // write the URL to the cache
597 cfg.setGroup( email );
598 cfg.writeEntry( "url", dirURL.prettyURL() ); // prettyURL() does not write user nor password
599 return dirURL;
600 }
601 }
602
603 return KURL();
604}
605
606KCal::FreeBusy *FreeBusyManager::iCalToFreeBusy( const TQCString &data )
607{
608 kdDebug(5850) << "FreeBusyManager::iCalToFreeBusy()" << endl;
609 kdDebug(5850) << data << endl;
610
611 TQString freeBusyVCal = TQString::fromUtf8( data );
612 KCal::FreeBusy *fb = mFormat.parseFreeBusy( freeBusyVCal );
613 if ( !fb ) {
614 kdDebug(5850) << "FreeBusyManager::iCalToFreeBusy(): Error parsing free/busy"
615 << endl;
616 kdDebug(5850) << freeBusyVCal << endl;
617 }
618 return fb;
619}
620
621TQString FreeBusyManager::freeBusyDir()
622{
623 return locateLocal( "data", "korganizer/freebusy" );
624}
625
626FreeBusy *FreeBusyManager::loadFreeBusy( const TQString &email )
627{
628 DEBUG_5850 << "FreeBusyManager::loadFreeBusy(): " << email << endl;
629
630 TQString fbd = freeBusyDir();
631
632 TQFile f( fbd + "/" + email + ".ifb" );
633 if ( !f.exists() ) {
634 DEBUG_5850 << "FreeBusyManager::loadFreeBusy() " << f.name()
635 << " doesn't exist." << endl;
636 return 0;
637 }
638
639 if ( !f.open( IO_ReadOnly ) ) {
640 DEBUG_5850 << "FreeBusyManager::loadFreeBusy() Unable to open file "
641 << f.name() << endl;
642 return 0;
643 }
644
645 TQTextStream ts( &f );
646 TQString str = ts.read();
647
648 return iCalToFreeBusy( str.utf8() );
649}
650
651bool FreeBusyManager::saveFreeBusy( FreeBusy *freebusy, const Person &person )
652{
653 DEBUG_5850 << "FreeBusyManager::saveFreeBusy(): " << person.fullName() << endl;
654
655 TQString fbd = freeBusyDir();
656
657 TQDir freeBusyDirectory( fbd );
658 if ( !freeBusyDirectory.exists() ) {
659 DEBUG_5850 << "Directory " << fbd << " does not exist!" << endl;
660 DEBUG_5850 << "Creating directory: " << fbd << endl;
661
662 if( !freeBusyDirectory.mkdir( fbd, true ) ) {
663 DEBUG_5850 << "Could not create directory: " << fbd << endl;
664 return false;
665 }
666 }
667
668 TQString filename( fbd );
669 filename += "/";
670 filename += person.email();
671 filename += ".ifb";
672 TQFile f( filename );
673
674 DEBUG_5850 << "FreeBusyManager::saveFreeBusy(): filename: " << filename
675 << endl;
676
677 freebusy->clearAttendees();
678 freebusy->setOrganizer( person );
679
680 TQString messageText = mFormat.createScheduleMessage( freebusy,
681 Scheduler::Publish );
682
683 if ( !f.open( IO_ReadWrite ) ) {
684 DEBUG_5850 << "acceptFreeBusy: Can't open:" << filename << " for writing"
685 << endl;
686 return false;
687 }
688 TQTextStream t( &f );
689 t << messageText;
690 f.close();
691
692 return true;
693}
694
695#include "freebusymanager.moc"
static KOrg::MainWindow * findInstance(const KURL &url)
Is there a instance with this URL?
Class for downloading FreeBusy Lists.
void setOrganizer(const Person &o)
interface for korganizer main window
Definition: mainwindow.h:41
virtual TQWidget * topLevelWidget()=0
Return widget whcih represents this main window.