Loading isis/src/base/apps/edrget/edrget.cpp +54 −6 Original line number Diff line number Diff line Loading @@ -3,6 +3,7 @@ #include <iostream> #include <QtCore> #include <QDir> #include "httpget.h" #include "ftpget.h" Loading @@ -17,13 +18,24 @@ using namespace std; void IsisMain() { // Get the file name from the GUI int timeOut = 60000; QString timeOutStr; UserInterface &ui = Application::GetUserInterface(); QString guiURL = ui.GetString("URL"); QString guiPath; if (ui.WasEntered("TOPATH")) { guiPath = ui.GetString("TOPATH"); } if (ui.WasEntered("TIMEOUT")) { timeOut = ui.GetInteger("TIMEOUT"); } QUrl qurl(guiURL); //test if scheme is ftp and set port if (qurl.scheme().toLower() == "ftp") { qurl.setPort(21); Loading @@ -33,14 +45,34 @@ void IsisMain() { if (ui.WasEntered("TOPATH") ) { parameters += " TOPATH=" + guiPath; } ////////////////////////////////////////////////////////////////////////////////// // tjw(ref#2259): The line below starts a child process that launches // $ISISROOT/bin/edrget . This was done because QMainWindow::instance()->exec() // which starts the event processing loop has already been called, and // cannot be called again to catch events from the FtpGet/HttpGet objects. // Launching a child process appears to have been a quick and dirty way // to get around this. This code should be refactored under a future ticket. // There is a lot of code duplication. ////////////////////////////////////////////////////////////////////////////////// ProgramLauncher::RunIsisProgram("edrget", parameters); } else { FtpGet getter; QObject::connect(&getter, SIGNAL(done()), QCoreApplication::instance(), SLOT(quit())); //a false getFile return means no error and we sould execute the get. if(!getter.getFile(qurl, guiPath)) QCoreApplication::instance()->exec(); //Starts the main event-processing loop for the application. Since IsisMain already //started an event-processing loop, a child process was launched above. if(!getter.getFile(qurl, guiPath,timeOut)) QCoreApplication::instance()->exec(); //if error occurred throw could not acquire if (getter.error() ) { QString localFileName; Loading @@ -49,8 +81,11 @@ void IsisMain() { localFileName += "/"; } localFileName += QFileInfo(qurl.path()).fileName(); QString localFileNameStr(localFileName); QFile::remove(localFileNameStr); QFile::remove(localFileName); //tested QString msg = "Could not acquire [" + guiURL + "]"; throw IException(IException::User, msg, _FILEINFO_); } Loading @@ -65,13 +100,24 @@ void IsisMain() { if (ui.WasEntered("TOPATH") ) { parameters += " TOPATH=" + guiPath; } //tjw //if (ui.WasEntered("TIMEOUT") ){ // // parameters += " TIMEOUT="+timeOutStr.setNum(timeOut); //} ProgramLauncher::RunIsisProgram("edrget", parameters); } else { HttpGet getter; QObject::connect(&getter, SIGNAL(done()), QCoreApplication::instance(), SLOT(quit())); //a false getFile return means no error and we sould execute the get. if(!getter.getFile(qurl, guiPath)) QCoreApplication::instance()->exec(); if (!getter.getFile(qurl, guiPath,timeOut)) QCoreApplication::instance()->exec(); //if error occurred then throw could not acquire if (getter.error() ) { QString localFileName; Loading @@ -79,8 +125,10 @@ void IsisMain() { localFileName += guiPath; localFileName += "/"; } QString localFileNameStr(localFileName); QFile::remove(localFileNameStr); //tjw localFileName += QFileInfo(qurl.path()).fileName(); //tested QFile::remove(localFileName); QString msg = "Could not acquire [" + guiURL + "]"; throw IException(IException::User, msg, _FILEINFO_); } Loading isis/src/base/apps/edrget/edrget.xml +26 −2 Original line number Diff line number Diff line <?xml version="1.0" encoding="UTF-8"?> <application name="edrget" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="http://isis.astrogeology.usgs.gov/Schemas/Application/application.xsd"> <application name="edrget" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation= "http://isis.astrogeology.usgs.gov/Schemas/Application/application.xsd"> <brief> Download network file using FTP or HTTP protocol. </brief> Loading Loading @@ -32,9 +34,14 @@ <change name="Steven Lambright" date="2007-08-14"> Added an application test </change> <change name="Tyler Wilson" date ="2015-09-14"> Added a timeout event handler to gracefully exit the application in the event the ftp server response time becomes too long. </change> </history> <groups> <group name="Files"> <parameter name="URL"> Loading @@ -51,7 +58,6 @@ </p> </description> </parameter> <parameter name="TOPATH"> <type>string</type> <brief>The path to the output file </brief> Loading @@ -65,6 +71,24 @@ </parameter> </group> <group name = "Timeout (ms)"> <parameter name ="TIMEOUT"> <type>integer</type> <brief>Timeout (in milliseconds) for file requests.</brief> <description> If the application does not hear from the server in the allotted amount of time, it quits and displays an error. </description> <internalDefault> 60000 </internalDefault> </parameter> </group> </groups> </application> isis/src/base/apps/edrget/ftpget.cpp +137 −27 Original line number Diff line number Diff line #include <QtCore> #include <QtNetwork> #include <iostream> #include "Application.h" #include "ftpget.h" #include "IString.h" #include "IException.h" #include "Progress.h" #include "Application.h" #include <iostream> #include <QtCore> #include <QtNetwork> using namespace std; namespace Isis { FtpGet::FtpGet(QObject *parent) : QObject(parent) { //conncet the Qftp done signal to the ftpDone function //connect the Qftp done signal to the ftpDone function connect(&p_ftp, SIGNAL(done(bool)), this, SLOT(ftpDone(bool) ) ); //connect the Qftp progress signal to the ftpProgress function(ISIS progress) //tjw: connect the QFtp progress signal to the ftpProgress function(ISIS progress) connect(&p_ftp, SIGNAL(dataTransferProgress(qint64, qint64)), this, SLOT(ftpProgress(qint64, qint64))); //tjw: A timer for detecting network timeouts and exiting the application gracefully connect(&p_timer, SIGNAL(timeout()),this,SLOT(ftpTimeout() ) ); } //************************************** // getFile function will check URL, if URL is good function will connect, // login, and get the file. This function returns P_error. bool FtpGet::getFile(const QUrl &url, QString topath) { //************************************************************************* // getFile function will check URL, if URL is good, getFile will connect, // login, and get the file. This function returns p_error. //************************************************************************* bool FtpGet::getFile(const QUrl &url, QString topath, int timeout) { //tjw: p_timeOut = timeout; //next four if check the URL and return true is there is error. if (!url.isValid() ) { string msg = "invalid URL"; // iException::Message(iException::User, msg, _FILEINFO_); p_error = true; return p_error; } if(url.scheme().toLower() != "ftp") { string msg = "URL must start with 'ftp:'"; // iException::Message(iException::User, msg, _FILEINFO_); //tested QString msg = QString("Invalid URL"); p_progress.SetText(msg); if (!Application::GetUserInterface().IsInteractive() ) cout << msg.toStdString() << endl; p_error = true; return p_error; } //Dead code: This condition is already checked before the function is hit //if (url.scheme().toLower() != "ftp") { // QString msg = QString("URL must start with 'ftp:'"); // p_progress.SetText(msg); // if (!Application::GetUserInterface().IsInteractive() ) // cout << msg.toStdString() << endl; // p_error = true; // return p_error; //} //tested if (url.path().isEmpty() ) { string msg = "URL has no path"; // iException::Message(iException::User, msg, _FILEINFO_); QString msg = QString("URL has no path"); p_progress.SetText(msg); if (!Application::GetUserInterface().IsInteractive() ) cout << msg.toStdString() << endl; p_error = true; return p_error; } Loading @@ -48,18 +86,26 @@ namespace Isis { localFileName += topath; localFileName += "/"; } //tested localFileName += QFileInfo(url.path()).fileName(); if (localFileName.isEmpty() ) { string msg = "URL has no filename"; // iException::Message(iException::User, msg, _FILEINFO_); QString msg = QString("URL has no filename"); p_progress.SetText(msg); if (!Application::GetUserInterface().IsInteractive() ) cout << msg.toStdString() << endl; p_error = true; return p_error; } // check local file. p_file.setFileName(localFileName); if (!p_file.open(QIODevice::WriteOnly) ) { string msg = "Cannot open output file"; // iException::Message(iException::User, msg, _FILEINFO_); QString msg = QString("Cannot open output file"); p_progress.SetText(msg); if (!Application::GetUserInterface().IsInteractive() ) cout << msg.toStdString() << endl; p_error = true; return p_error; } Loading @@ -67,35 +113,92 @@ namespace Isis { p_ftp.connectToHost(url.host(), url.port() ); p_ftp.login(); p_ftp.get(url.path(), &p_file); p_lastDone = -1; p_error = false; return p_error; } void FtpGet::ftpDone(bool error) { if (error) { p_error = true; QString msg = p_ftp.errorString(); msg.remove("\n"); // iException::Message(iException::User, msg, _FILEINFO_); } else { p_error = false; } if (!p_error) { p_file.close(); // this was added because final size may not match progress size so // you do not get 100% processed if (!Application::GetUserInterface().IsInteractive() ) { cout << "100% Processed" << endl; } } emit done(); return; } //tjw: Timeout event handler monitors the ftp connection and gracefully //closes and exits the application if a timeout occurs. void FtpGet::ftpTimeout() { bool fileExists = false; bool fileRemoved = false; QString fileRemovedQStr; QString timeoutSecs = QString("Timeout error: An ftp get request exceeded ") + QString::number(p_timeOut)+ QString(" ms."); p_progress.SetText(timeoutSecs); if (!Application::GetUserInterface().IsInteractive() ) cout << timeoutSecs.toStdString() << endl; p_ftp.abort(); p_ftp.close(); fileExists = p_file.exists(); if (fileExists) { fileRemoved = p_file.remove(); } if (!fileExists || fileRemoved) fileRemovedQStr = p_file.fileName() + QString(" successfully deleted."); if (!Application::GetUserInterface().IsInteractive() ) cout << fileRemovedQStr.toStdString() << endl; emit done(); return; } // ftpProgress uses the ISIS progress class to track progress // tjw: ftpProgress uses the ISIS progress class to track progress void FtpGet::ftpProgress(qint64 done, qint64 total) { p_timer.start(p_timeOut); //double percentDone = 0; //percentDone = 100*((double)done/total); //cout << percentDone << endl; if (total == 0) return; if (total == -1) return; if (p_error) return; Loading @@ -104,10 +207,17 @@ namespace Isis { p_progress.SetMaximumSteps(total); p_progress.CheckStatus(); p_lastDone = 1; } while (p_lastDone <= done) { p_progress.CheckStatus(); p_lastDone++; } } } isis/src/base/apps/edrget/ftpget.h +15 −1 Original line number Diff line number Diff line Loading @@ -3,6 +3,7 @@ #include <QFile> #include <QFtp> #include <QTimer> #include "Progress.h" class QUrl; Loading @@ -18,7 +19,7 @@ namespace Isis { public: FtpGet(QObject *parent = 0); bool getFile(const QUrl &url, QString topath); bool getFile(const QUrl &url, QString topath,int timeout); bool error() const { return p_error; Loading @@ -29,17 +30,30 @@ namespace Isis { signals: void done(); //tjw void dataTransferProgress(qint64, qint64); private slots: void ftpDone(bool error); void ftpProgress(qint64 done, qint64 total); //tjw void ftpTimeout(); private: QFtp p_ftp; QFile p_file; bool p_error; int p_lastDone; Progress p_progress; int p_timeOut; QTimer p_timer; }; } #endif isis/src/base/apps/edrget/httpget.cpp +115 −15 Original line number Diff line number Diff line #include <QtCore> #include <QtNetwork> #include <iostream> #include "Application.h" #include "httpget.h" #include "IString.h" #include "IException.h" #include "IString.h" #include "Progress.h" #include <iostream> #include <QtCore> #include <QtNetwork> using namespace std; namespace Isis { HttpGet::HttpGet(QObject *parent) : QObject(parent) { //connect the QHttp done signal to the httpDone function connect(&p_http, SIGNAL(done(bool)), this, SLOT(httpDone(bool))); //connect the QHttp progress signal to the httpProgress function(Isis progress) connect(&p_http, SIGNAL(dataReadProgress(int, int)), this, SLOT(httpProgress(int, int))); //tjw: A timer for detecting network timeouts and exiting // the application gracefully connect(&p_timer, SIGNAL(timeout()),this,SLOT(httpTimeout() ) ); } //********************************************** //**************************************************************************** // getFile function will check URL, if URL is good the function will connect, // login, and get the file. This function returns p_error bool HttpGet::getFile(const QUrl &url, QString topath) { //**************************************************************************** bool HttpGet::getFile(const QUrl &url, QString topath,int timeout) { p_timeOut = timeout; //tested // The next four ifs will check the URL and return error is bad if (!url.isValid() ) { QString msg = "invalid URL"; QString msg = "Invalid URL"; p_progress.SetText(msg); if (!Application::GetUserInterface().IsInteractive() ) cout << msg.toStdString() << endl; // iException::Message(iException::User, msg, _FILEINFO_); p_error = true; return p_error; } if(url.scheme().toLower() != "http") { QString msg = "URL must start with 'http:'"; //Dead code: this condition is already checked before this function is entered //if (url.scheme().toLower() != "http") { // QString msg = "URL must start with 'http:'"; // p_progress.SetText(msg); // if (!Application::GetUserInterface().IsInteractive() ) // cout << msg.toStdString() << endl; // iException::Message(iException::User, msg, _FILEINFO_); p_error = true; return p_error; } //p_error = true; // return p_error; //} //tested if (url.path().isEmpty() ) { QString msg = "URL has no path"; p_progress.SetText(msg); if (!Application::GetUserInterface().IsInteractive() ) cout << msg.toStdString() << endl; // iException::Message(iException::User, msg, _FILEINFO_); p_error = true; return p_error; Loading @@ -49,8 +82,13 @@ namespace Isis { localFileName += "/"; } localFileName += QFileInfo(url.path()).fileName(); //tested if (localFileName.isEmpty() ) { QString msg = "URL has no filename"; p_progress.SetText(msg); if (!Application::GetUserInterface().IsInteractive() ) cout << msg.toStdString() << endl; // iException::Message(iException::User, msg, _FILEINFO_); p_error = true; return p_error; Loading @@ -59,6 +97,10 @@ namespace Isis { p_file.setFileName(localFileName); if (!p_file.open(QIODevice::WriteOnly) ) { QString msg = "Cannot open output file"; p_progress.SetText(msg); if (!Application::GetUserInterface().IsInteractive() ) cout << msg.toStdString() << endl; // iException::Message(iException::User, msg, _FILEINFO_); p_error = true; return p_error; Loading @@ -71,6 +113,48 @@ namespace Isis { return p_error; } //tjw: Timeout event handler monitors the http connection and gracefully //closes and exits the application if a timeout occurs. void HttpGet::httpTimeout() { bool fileExists = false; bool fileRemoved = false; QString fileRemovedQStr; QString timeoutSecs = QString("Timeout error: An http get request exceeded ") + QString::number(p_timeOut)+ QString(" ms."); p_progress.SetText(timeoutSecs); if (!Application::GetUserInterface().IsInteractive() ) cout << timeoutSecs.toStdString() << endl; p_http.close(); fileExists = p_file.exists(); if (fileExists) { fileRemoved = p_file.remove(); } if (!fileExists || fileRemoved) fileRemovedQStr = p_file.fileName() + QString(" successfully deleted."); p_progress.SetText(fileRemovedQStr); if (!Application::GetUserInterface().IsInteractive() ) cout << fileRemovedQStr.toStdString() << endl; emit done(); return; } void HttpGet::httpDone(bool error) { map <int, QString> errLUT; errLUT [204] = "No content"; Loading @@ -89,7 +173,8 @@ namespace Isis { QString msg = p_http.errorString(); // iException::Message(iException::User, msg, _FILEINFO_); } else if(p_http.lastResponse().statusCode() != 200 && p_http.lastResponse().statusCode() != 0) { else if (p_http.lastResponse().statusCode() != 200 && p_http.lastResponse().statusCode() != 0) { p_error = true; QString msg = "error code: [" + errLUT[p_http.lastResponse().statusCode()] + "]"; // iException::Message(iException::User, msg, _FILEINFO_); Loading @@ -97,12 +182,27 @@ namespace Isis { else { p_error = false; } if(!p_error) p_file.close(); if (!p_error) { if (!Application::GetUserInterface().IsInteractive() ) { cout << "100% Processed" << endl; } p_file.close(); } emit done(); return; } // This function setsup and useses Isis progress classs to track progress. void HttpGet::httpProgress(int done, int total) { p_timer.start(p_timeOut); //double percentDone = 0; //percentDone = 100*((double)done/total); if (total == 0) return; if (p_error) return; if (p_lastDone < 0) { Loading Loading
isis/src/base/apps/edrget/edrget.cpp +54 −6 Original line number Diff line number Diff line Loading @@ -3,6 +3,7 @@ #include <iostream> #include <QtCore> #include <QDir> #include "httpget.h" #include "ftpget.h" Loading @@ -17,13 +18,24 @@ using namespace std; void IsisMain() { // Get the file name from the GUI int timeOut = 60000; QString timeOutStr; UserInterface &ui = Application::GetUserInterface(); QString guiURL = ui.GetString("URL"); QString guiPath; if (ui.WasEntered("TOPATH")) { guiPath = ui.GetString("TOPATH"); } if (ui.WasEntered("TIMEOUT")) { timeOut = ui.GetInteger("TIMEOUT"); } QUrl qurl(guiURL); //test if scheme is ftp and set port if (qurl.scheme().toLower() == "ftp") { qurl.setPort(21); Loading @@ -33,14 +45,34 @@ void IsisMain() { if (ui.WasEntered("TOPATH") ) { parameters += " TOPATH=" + guiPath; } ////////////////////////////////////////////////////////////////////////////////// // tjw(ref#2259): The line below starts a child process that launches // $ISISROOT/bin/edrget . This was done because QMainWindow::instance()->exec() // which starts the event processing loop has already been called, and // cannot be called again to catch events from the FtpGet/HttpGet objects. // Launching a child process appears to have been a quick and dirty way // to get around this. This code should be refactored under a future ticket. // There is a lot of code duplication. ////////////////////////////////////////////////////////////////////////////////// ProgramLauncher::RunIsisProgram("edrget", parameters); } else { FtpGet getter; QObject::connect(&getter, SIGNAL(done()), QCoreApplication::instance(), SLOT(quit())); //a false getFile return means no error and we sould execute the get. if(!getter.getFile(qurl, guiPath)) QCoreApplication::instance()->exec(); //Starts the main event-processing loop for the application. Since IsisMain already //started an event-processing loop, a child process was launched above. if(!getter.getFile(qurl, guiPath,timeOut)) QCoreApplication::instance()->exec(); //if error occurred throw could not acquire if (getter.error() ) { QString localFileName; Loading @@ -49,8 +81,11 @@ void IsisMain() { localFileName += "/"; } localFileName += QFileInfo(qurl.path()).fileName(); QString localFileNameStr(localFileName); QFile::remove(localFileNameStr); QFile::remove(localFileName); //tested QString msg = "Could not acquire [" + guiURL + "]"; throw IException(IException::User, msg, _FILEINFO_); } Loading @@ -65,13 +100,24 @@ void IsisMain() { if (ui.WasEntered("TOPATH") ) { parameters += " TOPATH=" + guiPath; } //tjw //if (ui.WasEntered("TIMEOUT") ){ // // parameters += " TIMEOUT="+timeOutStr.setNum(timeOut); //} ProgramLauncher::RunIsisProgram("edrget", parameters); } else { HttpGet getter; QObject::connect(&getter, SIGNAL(done()), QCoreApplication::instance(), SLOT(quit())); //a false getFile return means no error and we sould execute the get. if(!getter.getFile(qurl, guiPath)) QCoreApplication::instance()->exec(); if (!getter.getFile(qurl, guiPath,timeOut)) QCoreApplication::instance()->exec(); //if error occurred then throw could not acquire if (getter.error() ) { QString localFileName; Loading @@ -79,8 +125,10 @@ void IsisMain() { localFileName += guiPath; localFileName += "/"; } QString localFileNameStr(localFileName); QFile::remove(localFileNameStr); //tjw localFileName += QFileInfo(qurl.path()).fileName(); //tested QFile::remove(localFileName); QString msg = "Could not acquire [" + guiURL + "]"; throw IException(IException::User, msg, _FILEINFO_); } Loading
isis/src/base/apps/edrget/edrget.xml +26 −2 Original line number Diff line number Diff line <?xml version="1.0" encoding="UTF-8"?> <application name="edrget" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="http://isis.astrogeology.usgs.gov/Schemas/Application/application.xsd"> <application name="edrget" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation= "http://isis.astrogeology.usgs.gov/Schemas/Application/application.xsd"> <brief> Download network file using FTP or HTTP protocol. </brief> Loading Loading @@ -32,9 +34,14 @@ <change name="Steven Lambright" date="2007-08-14"> Added an application test </change> <change name="Tyler Wilson" date ="2015-09-14"> Added a timeout event handler to gracefully exit the application in the event the ftp server response time becomes too long. </change> </history> <groups> <group name="Files"> <parameter name="URL"> Loading @@ -51,7 +58,6 @@ </p> </description> </parameter> <parameter name="TOPATH"> <type>string</type> <brief>The path to the output file </brief> Loading @@ -65,6 +71,24 @@ </parameter> </group> <group name = "Timeout (ms)"> <parameter name ="TIMEOUT"> <type>integer</type> <brief>Timeout (in milliseconds) for file requests.</brief> <description> If the application does not hear from the server in the allotted amount of time, it quits and displays an error. </description> <internalDefault> 60000 </internalDefault> </parameter> </group> </groups> </application>
isis/src/base/apps/edrget/ftpget.cpp +137 −27 Original line number Diff line number Diff line #include <QtCore> #include <QtNetwork> #include <iostream> #include "Application.h" #include "ftpget.h" #include "IString.h" #include "IException.h" #include "Progress.h" #include "Application.h" #include <iostream> #include <QtCore> #include <QtNetwork> using namespace std; namespace Isis { FtpGet::FtpGet(QObject *parent) : QObject(parent) { //conncet the Qftp done signal to the ftpDone function //connect the Qftp done signal to the ftpDone function connect(&p_ftp, SIGNAL(done(bool)), this, SLOT(ftpDone(bool) ) ); //connect the Qftp progress signal to the ftpProgress function(ISIS progress) //tjw: connect the QFtp progress signal to the ftpProgress function(ISIS progress) connect(&p_ftp, SIGNAL(dataTransferProgress(qint64, qint64)), this, SLOT(ftpProgress(qint64, qint64))); //tjw: A timer for detecting network timeouts and exiting the application gracefully connect(&p_timer, SIGNAL(timeout()),this,SLOT(ftpTimeout() ) ); } //************************************** // getFile function will check URL, if URL is good function will connect, // login, and get the file. This function returns P_error. bool FtpGet::getFile(const QUrl &url, QString topath) { //************************************************************************* // getFile function will check URL, if URL is good, getFile will connect, // login, and get the file. This function returns p_error. //************************************************************************* bool FtpGet::getFile(const QUrl &url, QString topath, int timeout) { //tjw: p_timeOut = timeout; //next four if check the URL and return true is there is error. if (!url.isValid() ) { string msg = "invalid URL"; // iException::Message(iException::User, msg, _FILEINFO_); p_error = true; return p_error; } if(url.scheme().toLower() != "ftp") { string msg = "URL must start with 'ftp:'"; // iException::Message(iException::User, msg, _FILEINFO_); //tested QString msg = QString("Invalid URL"); p_progress.SetText(msg); if (!Application::GetUserInterface().IsInteractive() ) cout << msg.toStdString() << endl; p_error = true; return p_error; } //Dead code: This condition is already checked before the function is hit //if (url.scheme().toLower() != "ftp") { // QString msg = QString("URL must start with 'ftp:'"); // p_progress.SetText(msg); // if (!Application::GetUserInterface().IsInteractive() ) // cout << msg.toStdString() << endl; // p_error = true; // return p_error; //} //tested if (url.path().isEmpty() ) { string msg = "URL has no path"; // iException::Message(iException::User, msg, _FILEINFO_); QString msg = QString("URL has no path"); p_progress.SetText(msg); if (!Application::GetUserInterface().IsInteractive() ) cout << msg.toStdString() << endl; p_error = true; return p_error; } Loading @@ -48,18 +86,26 @@ namespace Isis { localFileName += topath; localFileName += "/"; } //tested localFileName += QFileInfo(url.path()).fileName(); if (localFileName.isEmpty() ) { string msg = "URL has no filename"; // iException::Message(iException::User, msg, _FILEINFO_); QString msg = QString("URL has no filename"); p_progress.SetText(msg); if (!Application::GetUserInterface().IsInteractive() ) cout << msg.toStdString() << endl; p_error = true; return p_error; } // check local file. p_file.setFileName(localFileName); if (!p_file.open(QIODevice::WriteOnly) ) { string msg = "Cannot open output file"; // iException::Message(iException::User, msg, _FILEINFO_); QString msg = QString("Cannot open output file"); p_progress.SetText(msg); if (!Application::GetUserInterface().IsInteractive() ) cout << msg.toStdString() << endl; p_error = true; return p_error; } Loading @@ -67,35 +113,92 @@ namespace Isis { p_ftp.connectToHost(url.host(), url.port() ); p_ftp.login(); p_ftp.get(url.path(), &p_file); p_lastDone = -1; p_error = false; return p_error; } void FtpGet::ftpDone(bool error) { if (error) { p_error = true; QString msg = p_ftp.errorString(); msg.remove("\n"); // iException::Message(iException::User, msg, _FILEINFO_); } else { p_error = false; } if (!p_error) { p_file.close(); // this was added because final size may not match progress size so // you do not get 100% processed if (!Application::GetUserInterface().IsInteractive() ) { cout << "100% Processed" << endl; } } emit done(); return; } //tjw: Timeout event handler monitors the ftp connection and gracefully //closes and exits the application if a timeout occurs. void FtpGet::ftpTimeout() { bool fileExists = false; bool fileRemoved = false; QString fileRemovedQStr; QString timeoutSecs = QString("Timeout error: An ftp get request exceeded ") + QString::number(p_timeOut)+ QString(" ms."); p_progress.SetText(timeoutSecs); if (!Application::GetUserInterface().IsInteractive() ) cout << timeoutSecs.toStdString() << endl; p_ftp.abort(); p_ftp.close(); fileExists = p_file.exists(); if (fileExists) { fileRemoved = p_file.remove(); } if (!fileExists || fileRemoved) fileRemovedQStr = p_file.fileName() + QString(" successfully deleted."); if (!Application::GetUserInterface().IsInteractive() ) cout << fileRemovedQStr.toStdString() << endl; emit done(); return; } // ftpProgress uses the ISIS progress class to track progress // tjw: ftpProgress uses the ISIS progress class to track progress void FtpGet::ftpProgress(qint64 done, qint64 total) { p_timer.start(p_timeOut); //double percentDone = 0; //percentDone = 100*((double)done/total); //cout << percentDone << endl; if (total == 0) return; if (total == -1) return; if (p_error) return; Loading @@ -104,10 +207,17 @@ namespace Isis { p_progress.SetMaximumSteps(total); p_progress.CheckStatus(); p_lastDone = 1; } while (p_lastDone <= done) { p_progress.CheckStatus(); p_lastDone++; } } }
isis/src/base/apps/edrget/ftpget.h +15 −1 Original line number Diff line number Diff line Loading @@ -3,6 +3,7 @@ #include <QFile> #include <QFtp> #include <QTimer> #include "Progress.h" class QUrl; Loading @@ -18,7 +19,7 @@ namespace Isis { public: FtpGet(QObject *parent = 0); bool getFile(const QUrl &url, QString topath); bool getFile(const QUrl &url, QString topath,int timeout); bool error() const { return p_error; Loading @@ -29,17 +30,30 @@ namespace Isis { signals: void done(); //tjw void dataTransferProgress(qint64, qint64); private slots: void ftpDone(bool error); void ftpProgress(qint64 done, qint64 total); //tjw void ftpTimeout(); private: QFtp p_ftp; QFile p_file; bool p_error; int p_lastDone; Progress p_progress; int p_timeOut; QTimer p_timer; }; } #endif
isis/src/base/apps/edrget/httpget.cpp +115 −15 Original line number Diff line number Diff line #include <QtCore> #include <QtNetwork> #include <iostream> #include "Application.h" #include "httpget.h" #include "IString.h" #include "IException.h" #include "IString.h" #include "Progress.h" #include <iostream> #include <QtCore> #include <QtNetwork> using namespace std; namespace Isis { HttpGet::HttpGet(QObject *parent) : QObject(parent) { //connect the QHttp done signal to the httpDone function connect(&p_http, SIGNAL(done(bool)), this, SLOT(httpDone(bool))); //connect the QHttp progress signal to the httpProgress function(Isis progress) connect(&p_http, SIGNAL(dataReadProgress(int, int)), this, SLOT(httpProgress(int, int))); //tjw: A timer for detecting network timeouts and exiting // the application gracefully connect(&p_timer, SIGNAL(timeout()),this,SLOT(httpTimeout() ) ); } //********************************************** //**************************************************************************** // getFile function will check URL, if URL is good the function will connect, // login, and get the file. This function returns p_error bool HttpGet::getFile(const QUrl &url, QString topath) { //**************************************************************************** bool HttpGet::getFile(const QUrl &url, QString topath,int timeout) { p_timeOut = timeout; //tested // The next four ifs will check the URL and return error is bad if (!url.isValid() ) { QString msg = "invalid URL"; QString msg = "Invalid URL"; p_progress.SetText(msg); if (!Application::GetUserInterface().IsInteractive() ) cout << msg.toStdString() << endl; // iException::Message(iException::User, msg, _FILEINFO_); p_error = true; return p_error; } if(url.scheme().toLower() != "http") { QString msg = "URL must start with 'http:'"; //Dead code: this condition is already checked before this function is entered //if (url.scheme().toLower() != "http") { // QString msg = "URL must start with 'http:'"; // p_progress.SetText(msg); // if (!Application::GetUserInterface().IsInteractive() ) // cout << msg.toStdString() << endl; // iException::Message(iException::User, msg, _FILEINFO_); p_error = true; return p_error; } //p_error = true; // return p_error; //} //tested if (url.path().isEmpty() ) { QString msg = "URL has no path"; p_progress.SetText(msg); if (!Application::GetUserInterface().IsInteractive() ) cout << msg.toStdString() << endl; // iException::Message(iException::User, msg, _FILEINFO_); p_error = true; return p_error; Loading @@ -49,8 +82,13 @@ namespace Isis { localFileName += "/"; } localFileName += QFileInfo(url.path()).fileName(); //tested if (localFileName.isEmpty() ) { QString msg = "URL has no filename"; p_progress.SetText(msg); if (!Application::GetUserInterface().IsInteractive() ) cout << msg.toStdString() << endl; // iException::Message(iException::User, msg, _FILEINFO_); p_error = true; return p_error; Loading @@ -59,6 +97,10 @@ namespace Isis { p_file.setFileName(localFileName); if (!p_file.open(QIODevice::WriteOnly) ) { QString msg = "Cannot open output file"; p_progress.SetText(msg); if (!Application::GetUserInterface().IsInteractive() ) cout << msg.toStdString() << endl; // iException::Message(iException::User, msg, _FILEINFO_); p_error = true; return p_error; Loading @@ -71,6 +113,48 @@ namespace Isis { return p_error; } //tjw: Timeout event handler monitors the http connection and gracefully //closes and exits the application if a timeout occurs. void HttpGet::httpTimeout() { bool fileExists = false; bool fileRemoved = false; QString fileRemovedQStr; QString timeoutSecs = QString("Timeout error: An http get request exceeded ") + QString::number(p_timeOut)+ QString(" ms."); p_progress.SetText(timeoutSecs); if (!Application::GetUserInterface().IsInteractive() ) cout << timeoutSecs.toStdString() << endl; p_http.close(); fileExists = p_file.exists(); if (fileExists) { fileRemoved = p_file.remove(); } if (!fileExists || fileRemoved) fileRemovedQStr = p_file.fileName() + QString(" successfully deleted."); p_progress.SetText(fileRemovedQStr); if (!Application::GetUserInterface().IsInteractive() ) cout << fileRemovedQStr.toStdString() << endl; emit done(); return; } void HttpGet::httpDone(bool error) { map <int, QString> errLUT; errLUT [204] = "No content"; Loading @@ -89,7 +173,8 @@ namespace Isis { QString msg = p_http.errorString(); // iException::Message(iException::User, msg, _FILEINFO_); } else if(p_http.lastResponse().statusCode() != 200 && p_http.lastResponse().statusCode() != 0) { else if (p_http.lastResponse().statusCode() != 200 && p_http.lastResponse().statusCode() != 0) { p_error = true; QString msg = "error code: [" + errLUT[p_http.lastResponse().statusCode()] + "]"; // iException::Message(iException::User, msg, _FILEINFO_); Loading @@ -97,12 +182,27 @@ namespace Isis { else { p_error = false; } if(!p_error) p_file.close(); if (!p_error) { if (!Application::GetUserInterface().IsInteractive() ) { cout << "100% Processed" << endl; } p_file.close(); } emit done(); return; } // This function setsup and useses Isis progress classs to track progress. void HttpGet::httpProgress(int done, int total) { p_timer.start(p_timeOut); //double percentDone = 0; //percentDone = 100*((double)done/total); if (total == 0) return; if (p_error) return; if (p_lastDone < 0) { Loading