00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
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 }