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