NetworkRetriever.cpp

Go to the documentation of this file.
00001 /***************************************************************************
00002  *   Copyright (c) 2004 Werner Mayer <wmayer[at]users.sourceforge.net>     *
00003  *                                                                         *
00004  *   This file is part of the FreeCAD CAx development system.              *
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         *
00014  *   GNU Library General Public License for more details.                  *
00015  *                                                                         *
00016  *   You should have received a copy of the GNU Library General Public     *
00017  *   License along with this library; see the file COPYING.LIB. If not,    *
00018  *   write to the Free Software Foundation, Inc., 59 Temple Place,         *
00019  *   Suite 330, Boston, MA  02111-1307, USA                                *
00020  *                                                                         *
00021  ***************************************************************************/
00022 
00023 
00024 #include "PreCompiled.h"
00025 
00026 #ifndef _PreComp_
00027 # include <qapplication.h>
00028 # include <qdir.h>
00029 # include <qfileinfo.h>
00030 # include <qlineedit.h>
00031 # include <qmessagebox.h>
00032 # include <qtimer.h>
00033 #endif
00034 
00035 #include "NetworkRetriever.h"
00036 #include "Action.h"
00037 #include "BitmapFactory.h"
00038 #include "MainWindow.h"
00039 #include "ui_DlgAuthorization.h"
00040 #include "FileDialog.h"
00041 
00042 #include <App/Application.h>
00043 #include <Base/Console.h>
00044 
00045 using namespace Gui;
00046 using namespace Gui::Dialog;
00047 
00048 namespace Gui {
00049 
00050 struct NetworkRetrieverP
00051 {
00052     // wget options
00053     int tries;
00054     int level;
00055     QString outputFile;
00056     QString user;
00057     QString passwd;
00058     bool timeStamp;
00059     bool img;
00060     bool convert;
00061     bool recurse;
00062     bool folRel;
00063     bool html;
00064     bool nop;
00065     // wget argument
00066     QString startUrl;
00067 
00068     QString proxy;
00069     QString dir;
00070     bool fail;
00071 };
00072 
00073 } // namespace Gui
00074 
00075 /* TRANSLATOR Gui::NetworkRetriever */
00076 
00077 NetworkRetriever::NetworkRetriever( QObject * parent )
00078   : QObject( parent )
00079 {
00080     d = new NetworkRetrieverP;
00081     d->tries = 3;
00082     d->level = 1;
00083     d->timeStamp = false;
00084     d->img = false;
00085     d->html = false;
00086     d->convert = true;
00087     d->recurse = false;
00088     d->folRel = false;
00089     d->nop = false;
00090 
00091     wget = new QProcess(this);
00092 
00093     // if wgets exits emit signal
00094     connect(wget, SIGNAL(finished(int, QProcess::ExitStatus)), 
00095             this, SLOT(wgetFinished(int, QProcess::ExitStatus)));
00096 
00097     // if application quits kill wget immediately to avoid dangling processes
00098     connect( qApp, SIGNAL(lastWindowClosed()), wget, SLOT(kill()) );
00099 }
00100 
00101 NetworkRetriever::~NetworkRetriever()
00102 {
00103     delete wget;
00104     delete d;
00105 }
00106 
00116 void NetworkRetriever::testFailure()
00117 {
00118     if ( wget->state() == QProcess::Running )
00119     {
00120         d->fail = false;
00121         Base::Console().Message( tr("Download started...\n").toAscii() );
00122     }
00123 }
00124 
00129 void NetworkRetriever::setNumberOfTries( int tries )
00130 {
00131     d->tries = tries;
00132 }
00133 
00137 void NetworkRetriever::setOutputFile( const QString& out )
00138 {
00139     d->outputFile = out;
00140 }
00141 
00147 void NetworkRetriever::setEnableTimestamp(bool ts)
00148 {
00149     d->timeStamp = ts;
00150 }
00151 
00157 void NetworkRetriever::setProxy( const QString& proxy, const QString& user, const QString& passwd )
00158 {
00159     d->proxy = proxy;
00160     d->user = user;
00161     d->passwd = passwd;
00162 }
00163 
00171 void NetworkRetriever::setEnableRecursive( bool recursive, int level )
00172 {
00173     d->recurse = recursive;
00174     d->level = level;
00175 }
00176 
00181 void NetworkRetriever::setFollowRelative( bool folRel )
00182 {
00183     d->folRel = folRel;
00184 }
00185 
00190 void NetworkRetriever::setEnableConvert( bool convert )
00191 {
00192     d->convert = convert;
00193 }
00194 
00199 void NetworkRetriever::setFetchImages( bool img )
00200 {
00201     d->img = img;
00202 }
00203 
00208 void NetworkRetriever::setEnableHTMLExtension( bool html )
00209 {
00210     d->html = html;
00211 }
00212 
00216 void NetworkRetriever::setNoParent( bool nop )
00217 {
00218     d->nop = nop;
00219 }
00220 
00224 void NetworkRetriever::setOutputDirectory( const QString& dir )
00225 {
00226     d->dir = dir;
00227 }
00228 
00232 bool NetworkRetriever::startDownload( const QString& startUrl )
00233 {
00234     if ( !testWget() )
00235         return false;
00236 
00237     d->startUrl = startUrl;
00238 
00239     // proxy as environment variable
00240     if ( !d->proxy.isEmpty() )
00241     {
00242         QStringList env = wget->environment();
00243         env << QString::fromAscii("http_proxy=%1").arg(d->proxy);
00244         env << QString::fromAscii("ftp_proxy=%1").arg(d->proxy);
00245         wget->setEnvironment(env);
00246     }
00247     else
00248     {
00249         QStringList env = wget->environment();
00250         env.removeAll(QString::fromAscii("http_proxy=%1").arg(d->proxy));
00251         env.removeAll(QString::fromAscii("ftp_proxy=%1").arg(d->proxy));
00252         wget->setEnvironment(env);
00253     }
00254 
00255     QStringList wgetArguments;
00256 
00257     // since the wget option '--directory-prefix' seems not to work as expected
00258     // and QProcess::setWorkingDirectory() fails if the 'doc' directory doesn't
00259     // exist we must check for this and create it if needed.
00260     if ( !d->dir.isEmpty() )
00261     {
00262         QDir dir(d->dir);
00263         if ( dir.exists( d->dir ) == false )
00264         {
00265             if ( dir.mkdir( d->dir ) == false)
00266             {
00267                 Base::Console().Error("Directory '%s' could not be created.", (const char*)d->dir.toAscii());
00268                 return true; // please, no error message
00269             }
00270         }
00271 
00272         wget->setWorkingDirectory( dir.path() );
00273     }
00274 
00275     // user authentification
00276     if ( !d->proxy.isEmpty() )
00277     {
00278         if ( !d->user.isEmpty() )
00279         {
00280             wgetArguments << QString::fromAscii("--proxy-user=%1").arg( d->user );
00281             if ( !d->passwd.isEmpty() )
00282             {
00283                 wgetArguments << QString::fromAscii("--proxy-passwd=%1").arg( d->passwd );
00284             }
00285         }
00286     }
00287 
00288     // output file
00289     if ( !d->outputFile.isEmpty() )
00290         wgetArguments << QString::fromAscii("--output-document=%1").arg( d->outputFile );
00291     // timestamping enabled -> update newer files only
00292     if ( d->timeStamp )
00293         wgetArguments << QString::fromAscii("-N");
00294     // get all needed image files
00295     if ( d->img )
00296         wgetArguments << QString::fromAscii("-p");
00297     // follow relative links only
00298     if ( d->folRel )
00299         wgetArguments<< QString::fromAscii("-L");
00300     if ( d->recurse )
00301     {
00302         wgetArguments << QString::fromAscii("-r");
00303         wgetArguments << QString::fromAscii("--level=%1").arg( d->level );
00304     }
00305 
00306     if ( d->nop )
00307         wgetArguments << QString::fromAscii("-np");
00308 
00309     // convert absolute links in to relative
00310     if ( d->convert )
00311         wgetArguments << QString::fromAscii("-k");
00312     // number of tries
00313     wgetArguments << QString::fromAscii("--tries=%1").arg( d->tries );
00314     // use HTML file extension
00315     if ( d->html )
00316         wgetArguments << QString::fromAscii("-E");
00317 
00318     // start URL
00319     wgetArguments << startUrl;
00320 
00321 #ifdef FC_OS_LINUX
00322     // on Linux it seems that we have to change cwd
00323     QString cwd = QDir::currentPath ();
00324     if ( !d->dir.isEmpty() )
00325     {
00326         QDir::setCurrent(d->dir);
00327     }
00328 
00329     wget->start(QString::fromAscii("wget"), wgetArguments);
00330     QDir::setCurrent( cwd );
00331 #else
00332     wget->start(QString::fromAscii("wget"), wgetArguments);
00333 #endif
00334 
00335     return wget->state() == QProcess::Running;
00336 }
00337 
00341 bool NetworkRetriever::isDownloading() const
00342 {
00343     return wget->state() == QProcess::Running;
00344 }
00345 
00349 void NetworkRetriever::abort()
00350 {
00351     if ( wget->state() == QProcess::Running)
00352     {
00353         QTimer::singleShot( 2000, wget, SLOT( kill() ) );
00354     }
00355 }
00356 
00357 void NetworkRetriever::wgetFinished(int exitCode, QProcess::ExitStatus status)
00358 {
00359     wget->setReadChannel(QProcess::StandardError);
00360     if (wget->canReadLine()) {
00361         QByteArray data = wget->readAll();
00362         Base::Console().Warning(data);
00363     }
00364     wgetExited();
00365 }
00366 
00371 bool NetworkRetriever::testWget()
00372 {
00373     QProcess proc;
00374     proc.start(QString::fromAscii("wget"));
00375     bool ok = proc.state() == QProcess::Running;
00376     proc.kill();
00377     proc.waitForFinished();
00378     return ok;
00379 }
00380 
00381 // --------------------------------------------------------------------
00382 
00383 StdCmdDownloadOnlineHelp::StdCmdDownloadOnlineHelp( QObject * parent)
00384   : QObject(parent), Command("Std_DownloadOnlineHelp")
00385 {
00386     sGroup        = QT_TR_NOOP("Help");
00387     sMenuText     = QT_TR_NOOP("Download online help");
00388     sToolTipText  = QT_TR_NOOP("Download %1's online help");
00389     sWhatsThis    = QT_TR_NOOP("Download %1's online help");
00390     sStatusTip    = QT_TR_NOOP("Download %1's online help");
00391     sPixmap       = "help";
00392 
00393     wget = new NetworkRetriever( this );
00394     // downloading recursively and depth 5
00395     wget->setEnableRecursive( true, 5 );
00396     wget->setNumberOfTries( 3 );
00397     wget->setEnableHTMLExtension( true );
00398     wget->setEnableConvert( true );
00399 
00400     wget->setEnableTimestamp( true );
00401     wget->setFetchImages( true );
00402     wget->setFollowRelative( false );
00403     wget->setNoParent( true );
00404 
00405     connect( wget, SIGNAL( wgetExited() ), this, SLOT( wgetFinished() ) );
00406 }
00407 
00408 StdCmdDownloadOnlineHelp::~StdCmdDownloadOnlineHelp()
00409 {
00410     delete wget;
00411 }
00412 
00413 Action * StdCmdDownloadOnlineHelp::createAction(void)
00414 {
00415     Action *pcAction;
00416 
00417     QString exe = QString::fromAscii(App::GetApplication().getExecutableName());
00418     pcAction = new Action(this,getMainWindow());
00419     pcAction->setText(QCoreApplication::translate(
00420         this->className(), sMenuText, 0,
00421         QCoreApplication::CodecForTr));
00422     pcAction->setToolTip(QCoreApplication::translate(
00423         this->className(), sToolTipText, 0,
00424         QCoreApplication::CodecForTr).arg(exe));
00425     pcAction->setStatusTip(QCoreApplication::translate(
00426         this->className(), sStatusTip, 0,
00427         QCoreApplication::CodecForTr).arg(exe));
00428     pcAction->setWhatsThis(QCoreApplication::translate(
00429         this->className(), sWhatsThis, 0,
00430         QCoreApplication::CodecForTr).arg(exe));
00431     pcAction->setIcon(Gui::BitmapFactory().pixmap(sPixmap));
00432     pcAction->setShortcut(QString::fromAscii(sAccel));
00433 
00434     return pcAction;
00435 }
00436 
00437 void StdCmdDownloadOnlineHelp::languageChange()
00438 {
00439     if (_pcAction) {
00440         QString exe = QString::fromAscii(App::GetApplication().getExecutableName());
00441         _pcAction->setText(QCoreApplication::translate(
00442             this->className(), sMenuText, 0,
00443             QCoreApplication::CodecForTr));
00444         _pcAction->setToolTip(QCoreApplication::translate(
00445             this->className(), sToolTipText, 0,
00446             QCoreApplication::CodecForTr).arg(exe));
00447         _pcAction->setStatusTip(QCoreApplication::translate(
00448             this->className(), sStatusTip, 0,
00449             QCoreApplication::CodecForTr).arg(exe));
00450         _pcAction->setWhatsThis(QCoreApplication::translate(
00451             this->className(), sWhatsThis, 0,
00452             QCoreApplication::CodecForTr).arg(exe));
00453     }
00454 }
00455 
00456 void StdCmdDownloadOnlineHelp::activated(int iMsg)
00457 {
00458     if (!wget->isDownloading()) {
00459         ParameterGrp::handle hGrp = App::GetApplication().GetUserParameter().GetGroup("BaseApp");
00460         hGrp = hGrp->GetGroup("Preferences")->GetGroup("OnlineHelp");
00461         std::string url = hGrp->GetASCII("DownloadURL", "http://apps.sourceforge.net/mediawiki/free-cad/");
00462         std::string prx = hGrp->GetASCII("ProxyText", "");
00463         bool bUseProxy  = hGrp->GetBool ("UseProxy", false);
00464         bool bAuthor    = hGrp->GetBool ("Authorize", false);
00465 
00466         if (bUseProxy) {
00467             QString username = QString::null;
00468             QString password = QString::null;
00469 
00470             if (bAuthor) {
00471                 QDialog dlg(getMainWindow());
00472                 dlg.setModal(true);
00473                 Ui_DlgAuthorization ui;
00474                 ui.setupUi(&dlg);
00475 
00476                 if (dlg.exec() == QDialog::Accepted) {
00477                     username = ui.username->text();
00478                     password = ui.password->text();
00479                 }
00480             }
00481 
00482             wget->setProxy(QString::fromAscii(prx.c_str()), username, password);
00483         }
00484 
00485         int loop=3;
00486         bool canStart = false;
00487 
00488         // set output directory
00489         QString path = QString::fromUtf8(App::GetApplication().GetHomePath());
00490         path += QString::fromAscii("/doc/");
00491         ParameterGrp::handle hURLGrp = App::GetApplication().GetParameterGroupByPath("User parameter:BaseApp/Preferences/OnlineHelp");
00492         path = QString::fromUtf8(hURLGrp->GetASCII( "DownloadLocation", path.toAscii() ).c_str());
00493 
00494         while (loop > 0) {
00495             loop--;
00496             QFileInfo fi( path);
00497             if (!fi.exists()) {
00498                 if (QMessageBox::critical(getMainWindow(), tr("Non-existing directory"), 
00499                      tr("The directory '%1' does not exist.\n\n"
00500                         "Do you want to specify an existing directory?").arg(fi.filePath()), 
00501                      QMessageBox::Yes|QMessageBox::Default, QMessageBox::No|QMessageBox::Escape) != 
00502                      QMessageBox::Yes)
00503                 {
00504                     // exit the command
00505                     return;
00506                 }
00507                 else 
00508                 {
00509                     path = FileDialog::getExistingDirectory();
00510                     if ( path.isEmpty() )
00511                         return;
00512                 }
00513             }
00514 
00515             if (!fi.permission( QFile::WriteUser)) {
00516                 if (QMessageBox::critical(getMainWindow(), tr("Missing permission"), 
00517                      tr("You don't have write permission to '%1'\n\n"
00518                         "Do you want to specify another directory?").arg(fi.filePath()), 
00519                      QMessageBox::Yes|QMessageBox::Default, QMessageBox::No|QMessageBox::Escape) != 
00520                      QMessageBox::Yes)
00521                 {
00522                     // exit the command
00523                     return;
00524                 }
00525                 else {
00526                     path = FileDialog::getExistingDirectory();
00527                     if ( path.isEmpty() )
00528                         return;
00529                 }
00530             }
00531             else {
00532                 wget->setOutputDirectory( path );
00533                 canStart = true;
00534                 break;
00535             }
00536         }
00537 
00538         if (canStart) {
00539             bool ok = wget->startDownload(QString::fromAscii(url.c_str()));
00540             if ( ok == false )
00541                 Base::Console().Error("The tool 'wget' couldn't be found. Please check your installation.");
00542             else if ( wget->isDownloading() && _pcAction )
00543                 _pcAction->setText(tr("Stop downloading"));
00544         }
00545     }
00546     else // kill the process now
00547     {
00548         wget->abort();
00549     }
00550 }
00551 
00552 void StdCmdDownloadOnlineHelp::wgetFinished()
00553 {
00554     if (_pcAction)
00555         _pcAction->setText(QCoreApplication::translate(
00556             this->className(), sMenuText, 0,
00557             QCoreApplication::CodecForTr));
00558 }
00559 
00560 #include "moc_NetworkRetriever.cpp"
00561 

Generated on Wed Nov 23 19:00:24 2011 for FreeCAD by  doxygen 1.6.1