kabc
resourcenet.cpp
00001 /* 00002 This file is part of libkabc. 00003 Copyright (c) 2003 Tobias Koenig <tokoe@kde.org> 00004 00005 This library is free software; you can redistribute it and/or 00006 modify it under the terms of the GNU Library General Public 00007 License as published by the Free Software Foundation; either 00008 version 2 of the License, or (at your option) any later version. 00009 00010 This library is distributed in the hope that it will be useful, 00011 but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00013 Library General Public License for more details. 00014 00015 You should have received a copy of the GNU Library General Public License 00016 along with this library; see the file COPYING.LIB. If not, write to 00017 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 00018 Boston, MA 02110-1301, USA. 00019 */ 00020 00021 #include "resourcenet.h" 00022 #include "resourcenetconfig.h" 00023 00024 #include "kabc/addressbook.h" 00025 #include "kabc/formatfactory.h" 00026 #include "kabc/stdaddressbook.h" 00027 00028 #include <kio/netaccess.h> 00029 #include <kio/scheduler.h> 00030 #include <kdebug.h> 00031 #include <klocale.h> 00032 #include <ksavefile.h> 00033 #include <ktemporaryfile.h> 00034 #include <kurlrequester.h> 00035 #include <kconfiggroup.h> 00036 00037 #include <QtCore/QFile> 00038 00039 using namespace KABC; 00040 00041 class ResourceNet::ResourceNetPrivate 00042 { 00043 public: 00044 KIO::Job *mLoadJob; 00045 bool mIsLoading; 00046 00047 KIO::Job *mSaveJob; 00048 bool mIsSaving; 00049 }; 00050 00051 ResourceNet::ResourceNet() 00052 : Resource(), mFormat( 0 ), 00053 mTempFile( 0 ), 00054 d( new ResourceNetPrivate ) 00055 { 00056 init( KUrl(), QLatin1String( "vcard" ) ); 00057 } 00058 00059 ResourceNet::ResourceNet( const KConfigGroup &group ) 00060 : Resource( group ), mFormat( 0 ), 00061 mTempFile( 0 ), 00062 d( new ResourceNetPrivate ) 00063 { 00064 init( KUrl( group.readPathEntry( "NetUrl", QString() ) ), group.readEntry( "NetFormat" ) ); 00065 } 00066 00067 ResourceNet::ResourceNet( const KUrl &url, const QString &format ) 00068 : Resource(), mFormat( 0 ), 00069 mTempFile( 0 ), 00070 d( new ResourceNetPrivate ) 00071 { 00072 init( url, format ); 00073 } 00074 00075 void ResourceNet::init( const KUrl &url, const QString &format ) 00076 { 00077 d->mLoadJob = 0; 00078 d->mIsLoading = false; 00079 d->mSaveJob = 0; 00080 d->mIsSaving = false; 00081 00082 mFormatName = format; 00083 00084 FormatFactory *factory = FormatFactory::self(); 00085 mFormat = factory->format( mFormatName ); 00086 if ( !mFormat ) { 00087 mFormatName = QLatin1String( "vcard" ); 00088 mFormat = factory->format( mFormatName ); 00089 } 00090 00091 setUrl( url ); 00092 } 00093 00094 ResourceNet::~ResourceNet() 00095 { 00096 if ( d->mIsLoading ) { 00097 d->mLoadJob->kill(); 00098 } 00099 if ( d->mIsSaving ) { 00100 d->mSaveJob->kill(); 00101 } 00102 00103 delete d; 00104 d = 0; 00105 00106 delete mFormat; 00107 mFormat = 0; 00108 00109 deleteLocalTempFile(); 00110 } 00111 00112 void ResourceNet::writeConfig( KConfigGroup &group ) 00113 { 00114 Resource::writeConfig( group ); 00115 00116 group.writePathEntry( "NetUrl", mUrl.url() ); 00117 group.writeEntry( "NetFormat", mFormatName ); 00118 } 00119 00120 Ticket *ResourceNet::requestSaveTicket() 00121 { 00122 kDebug(); 00123 00124 return createTicket( this ); 00125 } 00126 00127 void ResourceNet::releaseSaveTicket( Ticket *ticket ) 00128 { 00129 delete ticket; 00130 } 00131 00132 bool ResourceNet::doOpen() 00133 { 00134 return true; 00135 } 00136 00137 void ResourceNet::doClose() 00138 { 00139 } 00140 00141 bool ResourceNet::load() 00142 { 00143 QString tempFile; 00144 00145 if ( !KIO::NetAccess::download( mUrl, tempFile, 0 ) ) { 00146 addressBook()->error( i18n( "Unable to download file '%1'.", mUrl.prettyUrl() ) ); 00147 return false; 00148 } 00149 00150 QFile file( tempFile ); 00151 if ( !file.open( QIODevice::ReadOnly ) ) { 00152 addressBook()->error( i18n( "Unable to open file '%1'.", tempFile ) ); 00153 KIO::NetAccess::removeTempFile( tempFile ); 00154 return false; 00155 } 00156 00157 bool result = clearAndLoad( &file ); 00158 if ( !result ) { 00159 addressBook()->error( i18n( "Problems parsing file '%1'.", tempFile ) ); 00160 } 00161 00162 KIO::NetAccess::removeTempFile( tempFile ); 00163 00164 return result; 00165 } 00166 00167 bool ResourceNet::clearAndLoad( QFile *file ) 00168 { 00169 clear(); 00170 return mFormat->loadAll( addressBook(), this, file ); 00171 } 00172 00173 bool ResourceNet::asyncLoad() 00174 { 00175 if ( d->mIsLoading ) { 00176 abortAsyncLoading(); 00177 } 00178 00179 if ( d->mIsSaving ) { 00180 kWarning() << "Aborted asyncLoad() because we're still saving!"; 00181 return false; 00182 } 00183 00184 bool ok = createLocalTempFile(); 00185 00186 if ( !ok ) { 00187 emit loadingError( this, i18n( "Unable to open file '%1'.", mTempFile->fileName() ) ); 00188 deleteLocalTempFile(); 00189 return false; 00190 } 00191 00192 KUrl dest; 00193 dest.setPath( mTempFile->fileName() ); 00194 00195 KIO::Scheduler::checkSlaveOnHold( true ); 00196 d->mLoadJob = KIO::file_copy( mUrl, dest, -1, KIO::Overwrite | KIO::HideProgressInfo ); 00197 d->mIsLoading = true; 00198 connect( d->mLoadJob, SIGNAL(result(KJob*)), 00199 this, SLOT(downloadFinished(KJob*)) ); 00200 00201 return true; 00202 } 00203 00204 void ResourceNet::abortAsyncLoading() 00205 { 00206 kDebug(); 00207 00208 if ( d->mLoadJob ) { 00209 d->mLoadJob->kill(); // result not emitted 00210 d->mLoadJob = 0; 00211 } 00212 00213 deleteLocalTempFile(); 00214 d->mIsLoading = false; 00215 } 00216 00217 void ResourceNet::abortAsyncSaving() 00218 { 00219 kDebug(); 00220 00221 if ( d->mSaveJob ) { 00222 d->mSaveJob->kill(); // result not emitted 00223 d->mSaveJob = 0; 00224 } 00225 00226 deleteLocalTempFile(); 00227 d->mIsSaving = false; 00228 } 00229 00230 bool ResourceNet::save( Ticket *ticket ) 00231 { 00232 Q_UNUSED( ticket ); 00233 kDebug(); 00234 00235 if ( d->mIsSaving ) { 00236 abortAsyncSaving(); 00237 } 00238 00239 KTemporaryFile tempFile; 00240 bool ok = tempFile.open(); 00241 00242 if ( ok ) { 00243 saveToFile( &tempFile ); 00244 tempFile.flush(); 00245 } 00246 00247 if ( !ok ) { 00248 addressBook()->error( i18n( "Unable to save file '%1'.", tempFile.fileName() ) ); 00249 return false; 00250 } 00251 00252 ok = KIO::NetAccess::upload( tempFile.fileName(), mUrl, 0 ); 00253 if ( !ok ) { 00254 addressBook()->error( i18n( "Unable to upload to '%1'.", mUrl.prettyUrl() ) ); 00255 } 00256 00257 return ok; 00258 } 00259 00260 bool ResourceNet::asyncSave( Ticket *ticket ) 00261 { 00262 Q_UNUSED( ticket ); 00263 kDebug(); 00264 00265 if ( d->mIsSaving ) { 00266 abortAsyncSaving(); 00267 } 00268 00269 if ( d->mIsLoading ) { 00270 kWarning() << "Aborted asyncSave() because we're still loading!"; 00271 return false; 00272 } 00273 00274 bool ok = createLocalTempFile(); 00275 if ( ok ) { 00276 saveToFile( mTempFile ); 00277 mTempFile->flush(); 00278 } 00279 00280 if ( !ok ) { 00281 emit savingError( this, i18n( "Unable to save file '%1'.", mTempFile->fileName() ) ); 00282 deleteLocalTempFile(); 00283 return false; 00284 } 00285 00286 KUrl src; 00287 src.setPath( mTempFile->fileName() ); 00288 00289 KIO::Scheduler::checkSlaveOnHold( true ); 00290 d->mIsSaving = true; 00291 d->mSaveJob = KIO::file_copy( src, mUrl, -1, KIO::Overwrite | KIO::HideProgressInfo ); 00292 connect( d->mSaveJob, SIGNAL(result(KJob*)), 00293 this, SLOT(uploadFinished(KJob*)) ); 00294 00295 return true; 00296 } 00297 00298 bool ResourceNet::createLocalTempFile() 00299 { 00300 deleteStaleTempFile(); 00301 mTempFile = new KTemporaryFile(); 00302 return mTempFile->open(); 00303 } 00304 00305 void ResourceNet::deleteStaleTempFile() 00306 { 00307 if ( hasTempFile() ) { 00308 kDebug() << "stale temp file detected" << mTempFile->fileName(); 00309 deleteLocalTempFile(); 00310 } 00311 } 00312 00313 void ResourceNet::deleteLocalTempFile() 00314 { 00315 delete mTempFile; 00316 mTempFile = 0; 00317 } 00318 00319 void ResourceNet::saveToFile( QFile *file ) 00320 { 00321 mFormat->saveAll( addressBook(), this, file ); 00322 } 00323 00324 void ResourceNet::setUrl( const KUrl &url ) 00325 { 00326 mUrl = url; 00327 } 00328 00329 KUrl ResourceNet::url() const 00330 { 00331 return mUrl; 00332 } 00333 00334 void ResourceNet::setFormat( const QString &name ) 00335 { 00336 mFormatName = name; 00337 delete mFormat; 00338 00339 FormatFactory *factory = FormatFactory::self(); 00340 mFormat = factory->format( mFormatName ); 00341 } 00342 00343 QString ResourceNet::format() const 00344 { 00345 return mFormatName; 00346 } 00347 00348 void ResourceNet::downloadFinished( KJob *job ) 00349 { 00350 Q_UNUSED( job ); 00351 kDebug(); 00352 00353 d->mIsLoading = false; 00354 00355 if ( !hasTempFile() ) { 00356 emit loadingError( this, i18n( "Download failed, could not create temporary file" ) ); 00357 return; 00358 } 00359 00360 QFile file( mTempFile->fileName() ); 00361 if ( file.open( QIODevice::ReadOnly ) ) { 00362 if ( clearAndLoad( &file ) ) { 00363 emit loadingFinished( this ); 00364 } else { 00365 emit loadingError( this, i18n( "Problems during parsing file '%1'.", 00366 mTempFile->fileName() ) ); 00367 } 00368 } else { 00369 emit loadingError( this, i18n( "Unable to open file '%1'.", 00370 mTempFile->fileName() ) ); 00371 } 00372 00373 deleteLocalTempFile(); 00374 } 00375 00376 void ResourceNet::uploadFinished( KJob *job ) 00377 { 00378 kDebug(); 00379 00380 d->mIsSaving = false; 00381 00382 if ( job->error() ) { 00383 emit savingError( this, job->errorString() ); 00384 } else { 00385 emit savingFinished( this ); 00386 } 00387 00388 deleteLocalTempFile(); 00389 } 00390 00391 #include "resourcenet.moc"
This file is part of the KDE documentation.
Documentation copyright © 1996-2012 The KDE developers.
Generated on Mon Aug 27 2012 22:10:24 by doxygen 1.7.5 written by Dimitri van Heesch, © 1997-2006
Documentation copyright © 1996-2012 The KDE developers.
Generated on Mon Aug 27 2012 22:10:24 by doxygen 1.7.5 written by Dimitri van Heesch, © 1997-2006
KDE's Doxygen guidelines are available online.