00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include <tqfile.h>
00022
00023 #include <kdebug.h>
00024 #include <tdeio/netaccess.h>
00025 #include <tdeio/scheduler.h>
00026 #include <tdelocale.h>
00027 #include <ksavefile.h>
00028 #include <tdetempfile.h>
00029 #include <kurlrequester.h>
00030
00031 #include "addressbook.h"
00032 #include "formatfactory.h"
00033 #include "resourcenetconfig.h"
00034 #include "stdaddressbook.h"
00035
00036 #include "resourcenet.h"
00037
00038 using namespace TDEABC;
00039
00040 class ResourceNet::ResourceNetPrivate
00041 {
00042 public:
00043 TDEIO::Job *mLoadJob;
00044 bool mIsLoading;
00045
00046 TDEIO::Job *mSaveJob;
00047 bool mIsSaving;
00048
00049 TQString mLastErrorString;
00050 };
00051
00052 ResourceNet::ResourceNet( const TDEConfig *config )
00053 : Resource( config ), mFormat( 0 ),
00054 mTempFile( 0 ),
00055 d( new ResourceNetPrivate )
00056 {
00057 if ( config ) {
00058 init( KURL( config->readPathEntry( "NetUrl" ) ), config->readEntry( "NetFormat" ) );
00059 } else {
00060 init( KURL(), TQString("vcard").latin1() );
00061 }
00062 }
00063
00064 ResourceNet::ResourceNet( const KURL &url, const TQString &format )
00065 : Resource( 0 ), mFormat( 0 ),
00066 mTempFile( 0 ),
00067 d( new ResourceNetPrivate )
00068 {
00069 init( url, format );
00070 }
00071
00072 void ResourceNet::init( const KURL &url, const TQString &format )
00073 {
00074 d->mLoadJob = 0;
00075 d->mIsLoading = false;
00076 d->mSaveJob = 0;
00077 d->mIsSaving = false;
00078
00079 mFormatName = format;
00080
00081 FormatFactory *factory = FormatFactory::self();
00082 mFormat = factory->format( mFormatName );
00083 if ( !mFormat ) {
00084 mFormatName = TQString("vcard").latin1();
00085 mFormat = factory->format( mFormatName );
00086 }
00087
00088 setUrl( url );
00089 }
00090
00091 ResourceNet::~ResourceNet()
00092 {
00093 if ( d->mIsLoading )
00094 d->mLoadJob->kill();
00095 if ( d->mIsSaving )
00096 d->mSaveJob->kill();
00097
00098 delete d;
00099 d = 0;
00100
00101 delete mFormat;
00102 mFormat = 0;
00103
00104 deleteLocalTempFile();
00105 }
00106
00107 void ResourceNet::writeConfig( TDEConfig *config )
00108 {
00109 Resource::writeConfig( config );
00110
00111 config->writePathEntry( "NetUrl", mUrl.url() );
00112 config->writeEntry( "NetFormat", mFormatName );
00113 }
00114
00115 Ticket *ResourceNet::requestSaveTicket()
00116 {
00117 kdDebug(5700) << "ResourceNet::requestSaveTicket()" << endl;
00118
00119 return createTicket( this );
00120 }
00121
00122 void ResourceNet::releaseSaveTicket( Ticket *ticket )
00123 {
00124 delete ticket;
00125 }
00126
00127 bool ResourceNet::doOpen()
00128 {
00129 return true;
00130 }
00131
00132 void ResourceNet::doClose()
00133 {
00134 }
00135
00136 bool ResourceNet::load()
00137 {
00138 TQString tempFile;
00139
00140 if ( !TDEIO::NetAccess::download( mUrl, tempFile, 0 ) ) {
00141 addressBook()->error( i18n( "Unable to download file '%1'." ).arg( mUrl.prettyURL() ) );
00142 return false;
00143 }
00144
00145 TQFile file( tempFile );
00146 if ( !file.open( IO_ReadOnly ) ) {
00147 addressBook()->error( i18n( "Unable to open file '%1'." ).arg( tempFile ) );
00148 TDEIO::NetAccess::removeTempFile( tempFile );
00149 return false;
00150 }
00151
00152 bool result = clearAndLoad( &file );
00153 if ( !result )
00154 addressBook()->error( i18n( "Problems during parsing file '%1'." ).arg( tempFile ) );
00155
00156 TDEIO::NetAccess::removeTempFile( tempFile );
00157
00158 return result;
00159 }
00160
00161 bool ResourceNet::clearAndLoad( TQFile *file )
00162 {
00163 clear();
00164 return mFormat->loadAll( addressBook(), this, file );
00165 }
00166
00167 bool ResourceNet::asyncLoad()
00168 {
00169 if ( d->mIsLoading ) {
00170 abortAsyncLoading();
00171 }
00172
00173 if (d->mIsSaving) {
00174 kdWarning(5700) << "Aborted asyncLoad() because we're still asyncSave()ing!" << endl;
00175 return false;
00176 }
00177
00178 bool ok = createLocalTempFile();
00179 if ( ok )
00180 mTempFile->sync();
00181 ok = mTempFile->close();
00182
00183 if ( !ok ) {
00184 emit loadingError( this, i18n( "Unable to open file '%1'." ).arg( mTempFile->name() ) );
00185 deleteLocalTempFile();
00186 return false;
00187 }
00188
00189 KURL dest;
00190 dest.setPath( mTempFile->name() );
00191
00192 TDEIO::Scheduler::checkSlaveOnHold( true );
00193 d->mLoadJob = TDEIO::file_copy( mUrl, dest, -1, true, false, false );
00194 d->mIsLoading = true;
00195 connect( d->mLoadJob, TQT_SIGNAL( result( TDEIO::Job* ) ),
00196 this, TQT_SLOT( downloadFinished( TDEIO::Job* ) ) );
00197
00198 return true;
00199 }
00200
00201 void ResourceNet::abortAsyncLoading()
00202 {
00203 kdDebug(5700) << "ResourceNet::abortAsyncLoading()" << endl;
00204
00205 if ( d->mLoadJob ) {
00206 d->mLoadJob->kill();
00207 d->mLoadJob = 0;
00208 }
00209
00210 deleteLocalTempFile();
00211 d->mIsLoading = false;
00212 }
00213
00214 void ResourceNet::abortAsyncSaving()
00215 {
00216 kdDebug(5700) << "ResourceNet::abortAsyncSaving()" << endl;
00217
00218 if ( d->mSaveJob ) {
00219 d->mSaveJob->kill();
00220 d->mSaveJob = 0;
00221 }
00222
00223 deleteLocalTempFile();
00224 d->mIsSaving = false;
00225 }
00226
00227 bool ResourceNet::save( Ticket* )
00228 {
00229 kdDebug(5700) << "ResourceNet::save()" << endl;
00230
00231 if (d->mIsSaving) {
00232 abortAsyncSaving();
00233 }
00234
00235 KTempFile tempFile;
00236 tempFile.setAutoDelete( true );
00237 bool ok = false;
00238
00239 if ( tempFile.status() == 0 && tempFile.file() ) {
00240 saveToFile( tempFile.file() );
00241 tempFile.sync();
00242 ok = tempFile.close();
00243 }
00244
00245 if ( !ok ) {
00246 addressBook()->error( i18n( "Unable to save file '%1'." ).arg( tempFile.name() ) );
00247 return false;
00248 }
00249
00250 ok = TDEIO::NetAccess::upload( tempFile.name(), mUrl, 0 );
00251 if ( !ok )
00252 addressBook()->error( i18n( "Unable to upload to '%1'." ).arg( mUrl.prettyURL() ) );
00253
00254 return ok;
00255 }
00256
00257 bool ResourceNet::asyncSave( Ticket* )
00258 {
00259 kdDebug(5700) << "ResourceNet::asyncSave()" << endl;
00260
00261 if (d->mIsSaving) {
00262 abortAsyncSaving();
00263 }
00264
00265 if (d->mIsLoading) {
00266 kdWarning(5700) << "Aborted asyncSave() because we're still asyncLoad()ing!" << endl;
00267 return false;
00268 }
00269
00270 bool ok = createLocalTempFile();
00271 if ( ok ) {
00272 saveToFile( mTempFile->file() );
00273 mTempFile->sync();
00274 ok = mTempFile->close();
00275 }
00276
00277 if ( !ok ) {
00278 emit savingError( this, i18n( "Unable to save file '%1'." ).arg( mTempFile->name() ) );
00279 deleteLocalTempFile();
00280 return false;
00281 }
00282
00283 KURL src;
00284 src.setPath( mTempFile->name() );
00285
00286 TDEIO::Scheduler::checkSlaveOnHold( true );
00287 d->mIsSaving = true;
00288 d->mSaveJob = TDEIO::file_copy( src, mUrl, -1, true, false, false );
00289 connect( d->mSaveJob, TQT_SIGNAL( result( TDEIO::Job* ) ),
00290 this, TQT_SLOT( uploadFinished( TDEIO::Job* ) ) );
00291
00292 return true;
00293 }
00294
00295 bool ResourceNet::createLocalTempFile()
00296 {
00297 deleteStaleTempFile();
00298 mTempFile = new KTempFile();
00299 mTempFile->setAutoDelete( true );
00300 return mTempFile->status() == 0;
00301 }
00302
00303 void ResourceNet::deleteStaleTempFile()
00304 {
00305 if ( hasTempFile() ) {
00306 kdDebug(5700) << "stale temp file detected " << mTempFile->name() << endl;
00307 deleteLocalTempFile();
00308 }
00309 }
00310
00311 void ResourceNet::deleteLocalTempFile()
00312 {
00313 delete mTempFile;
00314 mTempFile = 0;
00315 }
00316
00317 void ResourceNet::saveToFile( TQFile *file )
00318 {
00319 mFormat->saveAll( addressBook(), this, file );
00320 }
00321
00322 void ResourceNet::setUrl( const KURL &url )
00323 {
00324 mUrl = url;
00325 }
00326
00327 KURL ResourceNet::url() const
00328 {
00329 return mUrl;
00330 }
00331
00332 void ResourceNet::setFormat( const TQString &name )
00333 {
00334 mFormatName = name;
00335 if ( mFormat )
00336 delete mFormat;
00337
00338 FormatFactory *factory = FormatFactory::self();
00339 mFormat = factory->format( mFormatName );
00340 }
00341
00342 TQString ResourceNet::format() const
00343 {
00344 return mFormatName;
00345 }
00346
00347 void ResourceNet::downloadFinished( TDEIO::Job* )
00348 {
00349 kdDebug(5700) << "ResourceNet::downloadFinished()" << endl;
00350
00351 d->mIsLoading = false;
00352
00353 if ( !hasTempFile() || mTempFile->status() != 0 ) {
00354 d->mLastErrorString = i18n( "Download failed: Unable to create temporary file" );
00355 TQTimer::singleShot( 0, this, TQT_SLOT( signalError() ) );
00356 return;
00357 }
00358
00359 TQFile file( mTempFile->name() );
00360 if ( file.open( IO_ReadOnly ) ) {
00361 if ( clearAndLoad( &file ) )
00362 emit loadingFinished( this );
00363 else
00364 emit loadingError( this, i18n( "Problems during parsing file '%1'." ).arg( mTempFile->name() ) );
00365 }
00366 else {
00367 emit loadingError( this, i18n( "Unable to open file '%1'." ).arg( mTempFile->name() ) );
00368 }
00369
00370 deleteLocalTempFile();
00371 }
00372
00373 void ResourceNet::uploadFinished( TDEIO::Job *job )
00374 {
00375 kdDebug(5700) << "ResourceFile::uploadFinished()" << endl;
00376
00377 d->mIsSaving = false;
00378
00379 if ( job->error() )
00380 emit savingError( this, job->errorString() );
00381 else
00382 emit savingFinished( this );
00383
00384 deleteLocalTempFile();
00385 }
00386
00387 void ResourceNet::signalError()
00388 {
00389 emit loadingError( this, d->mLastErrorString );
00390 d->mLastErrorString.truncate( 0 );
00391 }
00392
00393 #include "resourcenet.moc"