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