engine.cpp
00001 /* 00002 This file is part of KOrganizer. 00003 Copyright (c) 2002 Cornelius Schumacher <schumacher@kde.org> 00004 Copyright (c) 2014 Timothy Pearson <kb9vqf@pearsoncomputing.net> 00005 00006 This library is free software; you can redistribute it and/or 00007 modify it under the terms of the GNU Library General Public 00008 License as published by the Free Software Foundation; either 00009 version 2 of the License, or (at your option) any later version. 00010 00011 This library is distributed in the hope that it will be useful, 00012 but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00014 Library General Public License for more details. 00015 00016 You should have received a copy of the GNU Library General Public License 00017 along with this library; see the file COPYING.LIB. If not, write to 00018 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 00019 Boston, MA 02110-1301, USA. 00020 */ 00021 00022 #include <tqcstring.h> 00023 #include <tqdom.h> 00024 #include <tqfileinfo.h> 00025 00026 #include <tdeapplication.h> 00027 #include <kdebug.h> 00028 #include <tdeio/job.h> 00029 #include <tdelocale.h> 00030 #include <tdemessagebox.h> 00031 #include <kstandarddirs.h> 00032 00033 #include "knewstuff.h" 00034 #include "downloaddialog.h" 00035 #include "uploaddialog.h" 00036 #include "providerdialog.h" 00037 00038 #include "engine.h" 00039 #include "engine.moc" 00040 00041 using namespace KNS; 00042 00043 struct Engine::Private 00044 { 00045 bool mIgnoreInstallResult; 00046 TDENewStuff *mNewStuff; 00047 }; 00048 00049 Engine::Engine( TDENewStuff *newStuff, const TQString &type, 00050 TQWidget *parentWidget ) : 00051 mParentWidget( parentWidget ), mDownloadDialog( 0 ), 00052 mUploadDialog( 0 ), mProviderDialog( 0 ), mUploadProvider( 0 ), 00053 d(new Private), mType( type ) 00054 { 00055 d->mNewStuff = newStuff; 00056 d->mIgnoreInstallResult = false; 00057 mProviderLoader = new ProviderLoader( mParentWidget ); 00058 } 00059 00060 Engine::Engine( TDENewStuff *newStuff, const TQString &type, 00061 const TQString &providerList, TQWidget *parentWidget ) : 00062 mParentWidget( parentWidget ), 00063 mDownloadDialog( 0 ), mUploadDialog( 0 ), 00064 mProviderDialog( 0 ), mUploadProvider( 0 ), 00065 mProviderList( providerList ), d(new Private), 00066 mType( type ) 00067 { 00068 d->mNewStuff = newStuff; 00069 d->mIgnoreInstallResult = false; 00070 mProviderLoader = new ProviderLoader( mParentWidget ); 00071 } 00072 00073 Engine::~Engine() 00074 { 00075 delete d; 00076 delete mProviderLoader; 00077 00078 delete mUploadDialog; 00079 delete mDownloadDialog; 00080 } 00081 00082 void Engine::download() 00083 { 00084 kdDebug() << "Engine::download()" << endl; 00085 00086 connect( mProviderLoader, 00087 TQT_SIGNAL( providersLoaded( Provider::List * ) ), 00088 TQT_SLOT( getMetaInformation( Provider::List * ) ) ); 00089 mProviderLoader->load( mType, mProviderList ); 00090 } 00091 00092 void Engine::getMetaInformation( Provider::List *providers ) 00093 { 00094 mProviderLoader->disconnect(); 00095 00096 mNewStuffJobData.clear(); 00097 00098 if ( !mDownloadDialog ) { 00099 mDownloadDialog = new DownloadDialog( this, mParentWidget ); 00100 mDownloadDialog->show(); 00101 } 00102 mDownloadDialog->clear(); 00103 00104 Provider *p; 00105 for ( p = providers->first(); p; p = providers->next() ) { 00106 if ( p->downloadUrl().isEmpty() ) continue; 00107 00108 TDEIO::TransferJob *job = TDEIO::get( p->downloadUrl(), false, false ); 00109 connect( job, TQT_SIGNAL( result( TDEIO::Job * ) ), 00110 TQT_SLOT( slotNewStuffJobResult( TDEIO::Job * ) ) ); 00111 connect( job, TQT_SIGNAL( data( TDEIO::Job *, const TQByteArray & ) ), 00112 TQT_SLOT( slotNewStuffJobData( TDEIO::Job *, const TQByteArray & ) ) ); 00113 00114 mNewStuffJobData.insert( job, "" ); 00115 mProviderJobs[ job ] = p; 00116 } 00117 } 00118 00119 void Engine::slotNewStuffJobData( TDEIO::Job *job, const TQByteArray &data ) 00120 { 00121 if ( data.isEmpty() ) return; 00122 00123 kdDebug() << "Engine:slotNewStuffJobData()" << endl; 00124 00125 TQCString str( data, data.size() + 1 ); 00126 00127 mNewStuffJobData[ job ].append( TQString::fromUtf8( str ) ); 00128 } 00129 00130 void Engine::slotNewStuffJobResult( TDEIO::Job *job ) 00131 { 00132 if ( job->error() ) { 00133 kdDebug() << "Error downloading new stuff descriptions." << endl; 00134 job->showErrorDialog( mParentWidget ); 00135 } else { 00136 TQString knewstuffDoc = mNewStuffJobData[ job ]; 00137 00138 kdDebug() << "---START---" << endl << knewstuffDoc << "---END---" << endl; 00139 00140 mDownloadDialog->addProvider( mProviderJobs[ job ] ); 00141 00142 TQDomDocument doc; 00143 if ( !doc.setContent( knewstuffDoc ) ) { 00144 kdDebug() << "Error parsing OCS response." << endl; 00145 return; 00146 } 00147 else { 00148 TQDomElement knewstuff = doc.documentElement(); 00149 00150 if ( knewstuff.isNull() ) { 00151 kdDebug() << "No document in OCS response." << endl; 00152 } 00153 else { 00154 TQDomElement content; 00155 for(TQDomNode pn = knewstuff.firstChild(); !pn.isNull(); pn = pn.nextSibling()) 00156 { 00157 TQDomElement stuff = pn.toElement(); 00158 00159 if(stuff.tagName() == "data") 00160 { 00161 content = pn.toElement(); 00162 } 00163 } 00164 00165 if ( content.isNull() ) { 00166 kdDebug() << "No content in OCS response." << endl; 00167 } 00168 else { 00169 TQDomNode p; 00170 for ( p = content.firstChild(); !p.isNull(); p = p.nextSibling() ) { 00171 TQDomElement stuff = p.toElement(); 00172 if ( stuff.tagName() != "content" ) continue; 00173 00174 Entry *entry = new Entry( stuff ); 00175 00176 mDownloadDialog->show(); 00177 00178 mDownloadDialog->addEntry( entry ); 00179 00180 kdDebug() << "KNEWSTUFF: " << entry->name() << endl; 00181 00182 kdDebug() << " SUMMARY: " << entry->summary() << endl; 00183 kdDebug() << " VERSION: " << entry->version() << endl; 00184 kdDebug() << " RELEASEDATE: " << TQString(entry->releaseDate().toString()) << endl; 00185 kdDebug() << " RATING: " << entry->rating() << endl; 00186 00187 kdDebug() << " LANGS: " << entry->langs().join(", ") << endl; 00188 } 00189 } 00190 } 00191 } 00192 } 00193 00194 mNewStuffJobData.remove( job ); 00195 mProviderJobs.remove( job ); 00196 00197 if ( mNewStuffJobData.count() == 0 ) { 00198 mDownloadDialog->show(); 00199 mDownloadDialog->raise(); 00200 } 00201 } 00202 00203 void Engine::download( Entry *entry ) 00204 { 00205 kdDebug() << "Engine::download(entry)" << endl; 00206 00207 KURL source = entry->payload(); 00208 mDownloadDestination = d->mNewStuff->downloadDestination( entry ); 00209 00210 if ( mDownloadDestination.isEmpty() ) { 00211 kdDebug() << "Empty downloadDestination. Cancelling download." << endl; 00212 return; 00213 } 00214 00215 KURL destination = KURL( mDownloadDestination ); 00216 00217 kdDebug() << " SOURCE: " << source.url() << endl; 00218 kdDebug() << " DESTINATION: " << destination.url() << endl; 00219 00220 TDEIO::FileCopyJob *job = TDEIO::file_copy( source, destination, -1, true ); 00221 connect( job, TQT_SIGNAL( result( TDEIO::Job * ) ), 00222 TQT_SLOT( slotDownloadJobResult( TDEIO::Job * ) ) ); 00223 } 00224 00225 void Engine::slotDownloadJobResult( TDEIO::Job *job ) 00226 { 00227 if ( job->error() ) { 00228 kdDebug() << "Error downloading new stuff payload." << endl; 00229 job->showErrorDialog( mParentWidget ); 00230 return; 00231 } 00232 00233 if ( d->mNewStuff->install( mDownloadDestination ) ) { 00234 if ( !d->mIgnoreInstallResult ) { 00235 KMessageBox::information( mParentWidget, 00236 i18n("Successfully installed hot new stuff.") ); 00237 } 00238 } else 00239 if ( !d->mIgnoreInstallResult ){ 00240 KMessageBox::error( mParentWidget, 00241 i18n("Failed to install hot new stuff.") ); 00242 } 00243 } 00244 00245 void Engine::upload(const TQString &fileName, const TQString &previewName ) 00246 { 00247 mUploadFile = fileName; 00248 mPreviewFile = previewName; 00249 00250 connect( mProviderLoader, 00251 TQT_SIGNAL( providersLoaded( Provider::List * ) ), 00252 TQT_SLOT( selectUploadProvider( Provider::List * ) ) ); 00253 mProviderLoader->load( mType ); 00254 } 00255 00256 void Engine::selectUploadProvider( Provider::List *providers ) 00257 { 00258 kdDebug() << "Engine:selectUploadProvider()" << endl; 00259 00260 mProviderLoader->disconnect(); 00261 00262 if ( !mProviderDialog ) { 00263 mProviderDialog = new ProviderDialog( this, mParentWidget ); 00264 } 00265 00266 mProviderDialog->clear(); 00267 00268 mProviderDialog->show(); 00269 mProviderDialog->raise(); 00270 00271 for( Provider *p = providers->first(); p; p = providers->next() ) { 00272 mProviderDialog->addProvider( p ); 00273 } 00274 } 00275 00276 void Engine::requestMetaInformation( Provider *provider ) 00277 { 00278 mUploadProvider = provider; 00279 00280 if ( !mUploadDialog ) { 00281 mUploadDialog = new UploadDialog( this, mParentWidget ); 00282 } 00283 mUploadDialog->setPreviewFile( mPreviewFile ); 00284 mUploadDialog->setPayloadFile( mUploadFile ); 00285 mUploadDialog->show(); 00286 mUploadDialog->raise(); 00287 } 00288 00289 void Engine::upload( Entry *entry ) 00290 { 00291 if ( mUploadFile.isNull()) { 00292 mUploadFile = entry->fullName(); 00293 mUploadFile = locateLocal( "data", TQString(kapp->instanceName()) + "/upload/" + mUploadFile ); 00294 00295 if ( !d->mNewStuff->createUploadFile( mUploadFile ) ) { 00296 KMessageBox::error( mParentWidget, i18n("Unable to create file to upload.") ); 00297 emit uploadFinished( false ); 00298 return; 00299 } 00300 } 00301 00302 TQString lang = entry->langs().first(); 00303 TQFileInfo fi( mUploadFile ); 00304 entry->setPayload( KURL::fromPathOrURL( fi.fileName() ), lang ); 00305 00306 if ( !createMetaFile( entry ) ) { 00307 emit uploadFinished( false ); 00308 return; 00309 } 00310 00311 TQString text = i18n("The files to be uploaded have been created at:\n"); 00312 text.append( i18n("Data file: %1\n").arg( mUploadFile) ); 00313 if (!mPreviewFile.isEmpty()) { 00314 text.append( i18n("Preview image: %1\n").arg( mPreviewFile) ); 00315 } 00316 text.append( i18n("Content information: %1\n").arg( mUploadMetaFile) ); 00317 text.append( i18n("Those files can now be uploaded.\n") ); 00318 text.append( i18n("Beware that any people might have access to them at any time.") ); 00319 00320 TQString caption = i18n("Upload Files"); 00321 00322 if ( mUploadProvider->noUpload() ) { 00323 KURL noUploadUrl = mUploadProvider->noUploadUrl(); 00324 if ( noUploadUrl.isEmpty() ) { 00325 text.append( i18n("Please upload the files manually.") ); 00326 KMessageBox::information( mParentWidget, text, caption ); 00327 } else { 00328 int result = KMessageBox::questionYesNo( mParentWidget, text, caption, 00329 i18n("Upload Info"), 00330 KStdGuiItem::close() ); 00331 if ( result == KMessageBox::Yes ) { 00332 kapp->invokeBrowser( noUploadUrl.url() ); 00333 } 00334 } 00335 } else { 00336 int result = KMessageBox::questionYesNo( mParentWidget, text, caption, 00337 i18n("&Upload"), KStdGuiItem::cancel() ); 00338 if ( result == KMessageBox::Yes ) { 00339 KURL destination = mUploadProvider->uploadUrl(); 00340 destination.setFileName( fi.fileName() ); 00341 00342 TDEIO::FileCopyJob *job = TDEIO::file_copy( KURL::fromPathOrURL( mUploadFile ), destination ); 00343 connect( job, TQT_SIGNAL( result( TDEIO::Job * ) ), 00344 TQT_SLOT( slotUploadPayloadJobResult( TDEIO::Job * ) ) ); 00345 } else { 00346 emit uploadFinished( false ); 00347 } 00348 } 00349 } 00350 00351 bool Engine::createMetaFile( Entry *entry ) 00352 { 00353 TQDomDocument doc("knewstuff"); 00354 doc.appendChild( doc.createProcessingInstruction( 00355 "xml", "version=\"1.0\" encoding=\"UTF-8\"" ) ); 00356 TQDomElement de = doc.createElement("knewstuff"); 00357 doc.appendChild( de ); 00358 00359 entry->setType(type()); 00360 de.appendChild( entry->createDomElement( doc, de ) ); 00361 00362 kdDebug() << "--DOM START--" << endl << doc.toString() 00363 << "--DOM_END--" << endl; 00364 00365 if ( mUploadMetaFile.isNull() ) { 00366 mUploadMetaFile = entry->fullName() + ".meta"; 00367 mUploadMetaFile = locateLocal( "data", TQString(kapp->instanceName()) + "/upload/" + mUploadMetaFile ); 00368 } 00369 00370 TQFile f( mUploadMetaFile ); 00371 if ( !f.open( IO_WriteOnly ) ) { 00372 mUploadMetaFile = TQString::null; 00373 return false; 00374 } 00375 00376 TQTextStream ts( &f ); 00377 ts.setEncoding( TQTextStream::UnicodeUTF8 ); 00378 ts << doc.toString(); 00379 00380 f.close(); 00381 00382 return true; 00383 } 00384 00385 void Engine::slotUploadPayloadJobResult( TDEIO::Job *job ) 00386 { 00387 if ( job->error() ) { 00388 kdDebug() << "Error uploading new stuff payload." << endl; 00389 job->showErrorDialog( mParentWidget ); 00390 emit uploadFinished( false ); 00391 return; 00392 } 00393 00394 if (mPreviewFile.isEmpty()) { 00395 slotUploadPreviewJobResult(job); 00396 return; 00397 } 00398 00399 TQFileInfo fi( mPreviewFile ); 00400 00401 KURL previewDestination = mUploadProvider->uploadUrl(); 00402 previewDestination.setFileName( fi.fileName() ); 00403 00404 TDEIO::FileCopyJob *newJob = TDEIO::file_copy( KURL::fromPathOrURL( mPreviewFile ), previewDestination ); 00405 connect( newJob, TQT_SIGNAL( result( TDEIO::Job * ) ), 00406 TQT_SLOT( slotUploadPreviewJobResult( TDEIO::Job * ) ) ); 00407 } 00408 00409 void Engine::slotUploadPreviewJobResult( TDEIO::Job *job ) 00410 { 00411 if ( job->error() ) { 00412 kdDebug() << "Error uploading new stuff preview." << endl; 00413 job->showErrorDialog( mParentWidget ); 00414 emit uploadFinished( true ); 00415 return; 00416 } 00417 00418 TQFileInfo fi( mUploadMetaFile ); 00419 00420 KURL metaDestination = mUploadProvider->uploadUrl(); 00421 metaDestination.setFileName( fi.fileName() ); 00422 00423 TDEIO::FileCopyJob *newJob = TDEIO::file_copy( KURL::fromPathOrURL( mUploadMetaFile ), metaDestination ); 00424 connect( newJob, TQT_SIGNAL( result( TDEIO::Job * ) ), 00425 TQT_SLOT( slotUploadMetaJobResult( TDEIO::Job * ) ) ); 00426 } 00427 00428 void Engine::slotUploadMetaJobResult( TDEIO::Job *job ) 00429 { 00430 mUploadMetaFile = TQString::null; 00431 if ( job->error() ) { 00432 kdDebug() << "Error uploading new stuff metadata." << endl; 00433 job->showErrorDialog( mParentWidget ); 00434 emit uploadFinished( false ); 00435 return; 00436 } 00437 00438 KMessageBox::information( mParentWidget, 00439 i18n("Successfully uploaded new stuff.") ); 00440 emit uploadFinished( true ); 00441 } 00442 00443 void Engine::ignoreInstallResult(bool ignore) 00444 { 00445 d->mIgnoreInstallResult = ignore; 00446 }