00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include <qcstring.h>
00022 #include <qdom.h>
00023 #include <qfileinfo.h>
00024
00025 #include <kapplication.h>
00026 #include <kdebug.h>
00027 #include <kio/job.h>
00028 #include <klocale.h>
00029 #include <kmessagebox.h>
00030 #include <kstandarddirs.h>
00031
00032 #include "knewstuff.h"
00033 #include "downloaddialog.h"
00034 #include "uploaddialog.h"
00035 #include "providerdialog.h"
00036
00037 #include "engine.h"
00038 #include "engine.moc"
00039
00040 using namespace KNS;
00041
00042 struct Engine::Private
00043 {
00044 bool mIgnoreInstallResult;
00045 KNewStuff *mNewStuff;
00046 };
00047
00048 Engine::Engine( KNewStuff *newStuff, const QString &type,
00049 QWidget *parentWidget ) :
00050 mParentWidget( parentWidget ), mDownloadDialog( 0 ),
00051 mUploadDialog( 0 ), mProviderDialog( 0 ), mUploadProvider( 0 ),
00052 d(new Private), mType( type )
00053 {
00054 d->mNewStuff = newStuff;
00055 mProviderLoader = new ProviderLoader( mParentWidget );
00056
00057 mNewStuffList.setAutoDelete( true );
00058 }
00059
00060 Engine::Engine( KNewStuff *newStuff, const QString &type,
00061 const QString &providerList, QWidget *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 mNewStuffList.setAutoDelete( true );
00072 }
00073
00074 Engine::~Engine()
00075 {
00076 delete d;
00077 delete mProviderLoader;
00078
00079 delete mUploadDialog;
00080 delete mDownloadDialog;
00081 }
00082
00083 void Engine::download()
00084 {
00085 kdDebug(5850) << "Engine::download()" << endl;
00086
00087 connect( mProviderLoader,
00088 SIGNAL( providersLoaded( Provider::List * ) ),
00089 SLOT( getMetaInformation( Provider::List * ) ) );
00090 mProviderLoader->load( mType, mProviderList );
00091 }
00092
00093 void Engine::getMetaInformation( Provider::List *providers )
00094 {
00095 mProviderLoader->disconnect();
00096
00097 mNewStuffJobData.clear();
00098
00099 if ( !mDownloadDialog ) {
00100 mDownloadDialog = new DownloadDialog( this, mParentWidget );
00101 mDownloadDialog->show();
00102 }
00103 mDownloadDialog->clear();
00104
00105 Provider *p;
00106 for ( p = providers->first(); p; p = providers->next() ) {
00107 if ( p->downloadUrl().isEmpty() ) continue;
00108
00109 KIO::TransferJob *job = KIO::get( p->downloadUrl(), false, false );
00110 connect( job, SIGNAL( result( KIO::Job * ) ),
00111 SLOT( slotNewStuffJobResult( KIO::Job * ) ) );
00112 connect( job, SIGNAL( data( KIO::Job *, const QByteArray & ) ),
00113 SLOT( slotNewStuffJobData( KIO::Job *, const QByteArray & ) ) );
00114
00115 mNewStuffJobData.insert( job, "" );
00116 mProviderJobs[ job ] = p;
00117 }
00118 }
00119
00120 void Engine::slotNewStuffJobData( KIO::Job *job, const QByteArray &data )
00121 {
00122 if ( data.isEmpty() ) return;
00123
00124 kdDebug(5850) << "Engine:slotNewStuffJobData()" << endl;
00125
00126 QCString str( data, data.size() + 1 );
00127
00128 mNewStuffJobData[ job ].append( QString::fromUtf8( str ) );
00129 }
00130
00131 void Engine::slotNewStuffJobResult( KIO::Job *job )
00132 {
00133 if ( job->error() ) {
00134 kdDebug(5850) << "Error downloading new stuff descriptions." << endl;
00135 job->showErrorDialog( mParentWidget );
00136 } else {
00137 QString knewstuffDoc = mNewStuffJobData[ job ];
00138
00139 kdDebug(5850) << "---START---" << endl << knewstuffDoc << "---END---" << endl;
00140
00141 mDownloadDialog->addProvider( mProviderJobs[ job ] );
00142
00143 QDomDocument doc;
00144 if ( !doc.setContent( knewstuffDoc ) ) {
00145 kdDebug(5850) << "Error parsing knewstuff.xml." << endl;
00146 return;
00147 } else {
00148 QDomElement knewstuff = doc.documentElement();
00149
00150 if ( knewstuff.isNull() ) {
00151 kdDebug(5850) << "No document in knewstuffproviders.xml." << endl;
00152 } else {
00153 QDomNode p;
00154 for ( p = knewstuff.firstChild(); !p.isNull(); p = p.nextSibling() ) {
00155 QDomElement stuff = p.toElement();
00156 if ( stuff.tagName() != "stuff" ) continue;
00157 if ( stuff.attribute("type", mType) != mType ) continue;
00158
00159 Entry *entry = new Entry( stuff );
00160 mNewStuffList.append( entry );
00161
00162 mDownloadDialog->show();
00163
00164 mDownloadDialog->addEntry( entry );
00165
00166 kdDebug(5850) << "KNEWSTUFF: " << entry->name() << endl;
00167
00168 kdDebug(5850) << " SUMMARY: " << entry->summary() << endl;
00169 kdDebug(5850) << " VERSION: " << entry->version() << endl;
00170 kdDebug(5850) << " RELEASEDATE: " << entry->releaseDate().toString() << endl;
00171 kdDebug(5850) << " RATING: " << entry->rating() << endl;
00172
00173 kdDebug(5850) << " LANGS: " << entry->langs().join(", ") << endl;
00174 }
00175 }
00176 }
00177 }
00178
00179 mNewStuffJobData.remove( job );
00180 mProviderJobs.remove( job );
00181
00182 if ( mNewStuffJobData.count() == 0 ) {
00183 mDownloadDialog->show();
00184 mDownloadDialog->raise();
00185 }
00186 }
00187
00188 void Engine::download( Entry *entry )
00189 {
00190 kdDebug(5850) << "Engine::download(entry)" << endl;
00191
00192 KURL source = entry->payload();
00193 mDownloadDestination = d->mNewStuff->downloadDestination( entry );
00194
00195 if ( mDownloadDestination.isEmpty() ) {
00196 kdDebug(5850) << "Empty downloadDestination. Cancelling download." << endl;
00197 return;
00198 }
00199
00200 KURL destination = KURL( mDownloadDestination );
00201
00202 kdDebug(5850) << " SOURCE: " << source.url() << endl;
00203 kdDebug(5850) << " DESTINATION: " << destination.url() << endl;
00204
00205 KIO::FileCopyJob *job = KIO::file_copy( source, destination, -1, true );
00206 connect( job, SIGNAL( result( KIO::Job * ) ),
00207 SLOT( slotDownloadJobResult( KIO::Job * ) ) );
00208 }
00209
00210 void Engine::slotDownloadJobResult( KIO::Job *job )
00211 {
00212 if ( job->error() ) {
00213 kdDebug(5850) << "Error downloading new stuff payload." << endl;
00214 job->showErrorDialog( mParentWidget );
00215 return;
00216 }
00217
00218 if ( d->mNewStuff->install( mDownloadDestination ) ) {
00219 if ( !d->mIgnoreInstallResult ) {
00220 KMessageBox::information( mParentWidget,
00221 i18n("Successfully installed hot new stuff.") );
00222 }
00223 } else
00224 if ( !d->mIgnoreInstallResult ){
00225 KMessageBox::error( mParentWidget,
00226 i18n("Failed to install hot new stuff.") );
00227 }
00228 }
00229
00230 void Engine::upload(const QString &fileName, const QString &previewName )
00231 {
00232 mUploadFile = fileName;
00233 mPreviewFile = previewName;
00234
00235 connect( mProviderLoader,
00236 SIGNAL( providersLoaded( Provider::List * ) ),
00237 SLOT( selectUploadProvider( Provider::List * ) ) );
00238 mProviderLoader->load( mType );
00239 }
00240
00241 void Engine::selectUploadProvider( Provider::List *providers )
00242 {
00243 kdDebug(5850) << "Engine:selectUploadProvider()" << endl;
00244
00245 mProviderLoader->disconnect();
00246
00247 if ( !mProviderDialog ) {
00248 mProviderDialog = new ProviderDialog( this, mParentWidget );
00249 }
00250
00251 mProviderDialog->clear();
00252
00253 mProviderDialog->show();
00254 mProviderDialog->raise();
00255
00256 for( Provider *p = providers->first(); p; p = providers->next() ) {
00257 mProviderDialog->addProvider( p );
00258 }
00259 }
00260
00261 void Engine::requestMetaInformation( Provider *provider )
00262 {
00263 mUploadProvider = provider;
00264
00265 if ( !mUploadDialog ) {
00266 mUploadDialog = new UploadDialog( this, mParentWidget );
00267 }
00268 mUploadDialog->setPreviewFile( mPreviewFile );
00269 mUploadDialog->setPayloadFile( mUploadFile );
00270 mUploadDialog->show();
00271 mUploadDialog->raise();
00272 }
00273
00274 void Engine::upload( Entry *entry )
00275 {
00276 if ( mUploadFile.isNull()) {
00277 mUploadFile = entry->fullName();
00278 mUploadFile = locateLocal( "data", QString(kapp->instanceName()) + "/upload/" + mUploadFile );
00279
00280 if ( !d->mNewStuff->createUploadFile( mUploadFile ) ) {
00281 KMessageBox::error( mParentWidget, i18n("Unable to create file to upload.") );
00282 emit uploadFinished( false );
00283 return;
00284 }
00285 }
00286
00287 QString lang = entry->langs().first();
00288 QFileInfo fi( mUploadFile );
00289 entry->setPayload( KURL::fromPathOrURL( fi.fileName() ), lang );
00290
00291 if ( !createMetaFile( entry ) ) {
00292 emit uploadFinished( false );
00293 return;
00294 }
00295
00296 QString text = i18n("The files to be uploaded have been created at:\n");
00297 text.append( i18n("Data file: %1\n").arg( mUploadFile) );
00298 if (!mPreviewFile.isEmpty()) {
00299 text.append( i18n("Preview image: %1\n").arg( mPreviewFile) );
00300 }
00301 text.append( i18n("Content information: %1\n").arg( mUploadMetaFile) );
00302 text.append( i18n("Those files can now be uploaded.\n") );
00303 text.append( i18n("Beware that any people might have access to them at any time.") );
00304
00305 QString caption = i18n("Upload Files");
00306
00307 if ( mUploadProvider->noUpload() ) {
00308 KURL noUploadUrl = mUploadProvider->noUploadUrl();
00309 if ( noUploadUrl.isEmpty() ) {
00310 text.append( i18n("Please upload the files manually.") );
00311 KMessageBox::information( mParentWidget, text, caption );
00312 } else {
00313 int result = KMessageBox::questionYesNo( mParentWidget, text, caption,
00314 i18n("Upload Info"),
00315 KStdGuiItem::close() );
00316 if ( result == KMessageBox::Yes ) {
00317 kapp->invokeBrowser( noUploadUrl.url() );
00318 }
00319 }
00320 } else {
00321 int result = KMessageBox::questionYesNo( mParentWidget, text, caption,
00322 i18n("&Upload"), KStdGuiItem::cancel() );
00323 if ( result == KMessageBox::Yes ) {
00324 KURL destination = mUploadProvider->uploadUrl();
00325 destination.setFileName( fi.fileName() );
00326
00327 KIO::FileCopyJob *job = KIO::file_copy( KURL::fromPathOrURL( mUploadFile ), destination );
00328 connect( job, SIGNAL( result( KIO::Job * ) ),
00329 SLOT( slotUploadPayloadJobResult( KIO::Job * ) ) );
00330 } else {
00331 emit uploadFinished( false );
00332 }
00333 }
00334 }
00335
00336 bool Engine::createMetaFile( Entry *entry )
00337 {
00338 QDomDocument doc("knewstuff");
00339 doc.appendChild( doc.createProcessingInstruction(
00340 "xml", "version=\"1.0\" encoding=\"UTF-8\"" ) );
00341 QDomElement de = doc.createElement("knewstuff");
00342 doc.appendChild( de );
00343
00344 entry->setType(type());
00345 de.appendChild( entry->createDomElement( doc, de ) );
00346
00347 kdDebug(5850) << "--DOM START--" << endl << doc.toString()
00348 << "--DOM_END--" << endl;
00349
00350 if ( mUploadMetaFile.isNull() ) {
00351 mUploadMetaFile = entry->fullName() + ".meta";
00352 mUploadMetaFile = locateLocal( "data", QString(kapp->instanceName()) + "/upload/" + mUploadMetaFile );
00353 }
00354
00355 QFile f( mUploadMetaFile );
00356 if ( !f.open( IO_WriteOnly ) ) {
00357 mUploadMetaFile = QString::null;
00358 return false;
00359 }
00360
00361 QTextStream ts( &f );
00362 ts.setEncoding( QTextStream::UnicodeUTF8 );
00363 ts << doc.toString();
00364
00365 f.close();
00366
00367 return true;
00368 }
00369
00370 void Engine::slotUploadPayloadJobResult( KIO::Job *job )
00371 {
00372 if ( job->error() ) {
00373 kdDebug(5850) << "Error uploading new stuff payload." << endl;
00374 job->showErrorDialog( mParentWidget );
00375 emit uploadFinished( false );
00376 return;
00377 }
00378
00379 if (mPreviewFile.isEmpty()) {
00380 slotUploadPreviewJobResult(job);
00381 return;
00382 }
00383
00384 QFileInfo fi( mPreviewFile );
00385
00386 KURL previewDestination = mUploadProvider->uploadUrl();
00387 previewDestination.setFileName( fi.fileName() );
00388
00389 KIO::FileCopyJob *newJob = KIO::file_copy( KURL::fromPathOrURL( mPreviewFile ), previewDestination );
00390 connect( newJob, SIGNAL( result( KIO::Job * ) ),
00391 SLOT( slotUploadPreviewJobResult( KIO::Job * ) ) );
00392 }
00393
00394 void Engine::slotUploadPreviewJobResult( KIO::Job *job )
00395 {
00396 if ( job->error() ) {
00397 kdDebug(5850) << "Error uploading new stuff preview." << endl;
00398 job->showErrorDialog( mParentWidget );
00399 emit uploadFinished( true );
00400 return;
00401 }
00402
00403 QFileInfo fi( mUploadMetaFile );
00404
00405 KURL metaDestination = mUploadProvider->uploadUrl();
00406 metaDestination.setFileName( fi.fileName() );
00407
00408 KIO::FileCopyJob *newJob = KIO::file_copy( KURL::fromPathOrURL( mUploadMetaFile ), metaDestination );
00409 connect( newJob, SIGNAL( result( KIO::Job * ) ),
00410 SLOT( slotUploadMetaJobResult( KIO::Job * ) ) );
00411 }
00412
00413 void Engine::slotUploadMetaJobResult( KIO::Job *job )
00414 {
00415 mUploadMetaFile = QString::null;
00416 if ( job->error() ) {
00417 kdDebug(5850) << "Error uploading new stuff metadata." << endl;
00418 job->showErrorDialog( mParentWidget );
00419 emit uploadFinished( false );
00420 return;
00421 }
00422
00423 KMessageBox::information( mParentWidget,
00424 i18n("Successfully uploaded new stuff.") );
00425 emit uploadFinished( true );
00426 }
00427
00428 void Engine::ignoreInstallResult(bool ignore)
00429 {
00430 d->mIgnoreInstallResult = ignore;
00431 }