refactored the curl methods (read/write URL) into a separate utility class

This commit is contained in:
fgerlits 2006-05-12 12:15:31 +00:00
parent c82210fbc6
commit 65854d7073
8 changed files with 277 additions and 174 deletions

View file

@ -134,7 +134,8 @@ CORE_LIB_OBJS = ${TMP_DIR}/UniqueId.o \
${TMP_DIR}/SearchCriteria.o \
${TMP_DIR}/MetadataType.o \
${TMP_DIR}/MetadataTypeContainer.o \
${TMP_DIR}/OptionsContainer.o
${TMP_DIR}/OptionsContainer.o \
${TMP_DIR}/FileTools.o
TEST_RUNNER_OBJS = ${TMP_DIR}/TestRunner.o \
${TMP_DIR}/UuidTest.o \

View file

@ -0,0 +1,106 @@
/*------------------------------------------------------------------------------
Copyright (c) 2004 Media Development Loan Fund
This file is part of the LiveSupport project.
http://livesupport.campware.org/
To report bugs, send an e-mail to bugs@campware.org
LiveSupport is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
LiveSupport is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with LiveSupport; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Author : $Author: fgerlits $
Version : $Revision$
Location : $URL: svn+ssh://fgerlits@code.campware.org/home/svn/repo/livesupport/trunk/livesupport/src/modules/core/include/LiveSupport/Core/FileTools.h $
------------------------------------------------------------------------------*/
#ifndef LiveSupport_Core_FileTools_h
#define LiveSupport_Core_FileTools_h
#ifndef __cplusplus
#error This is a C++ include file
#endif
/* ============================================================ include files */
#ifdef HAVE_CONFIG_H
#include "configure.h"
#endif
#include <stdexcept>
#include "LiveSupport/Core/Ptr.h"
namespace LiveSupport {
namespace Core {
using namespace LiveSupport;
using namespace LiveSupport::Core;
/* ================================================================ constants */
/* =================================================================== macros */
/* =============================================================== data types */
/**
* A collection of tools for handling files and URLs.
*
* @author $Author: fgerlits $
* @version $Revision$
*/
class FileTools
{
public:
/**
* Copy the contents of a URL to a local file.
*
* @param url the URL to read.
* @param path the local path where the file is saved.
* @exception std::runtime_error on errors.
*/
static void
copyUrlToFile(const std::string & url,
const std::string & path)
throw (std::runtime_error);
/**
* Upload the contents of a local file to a writable URL.
*
* @param path the local path where the file is.
* @param url the URL to write.
* @exception std::runtime_error on errors.
*/
static void
copyFileToUrl(const std::string & path,
const std::string & url)
throw (std::runtime_error);
};
/* ================================================= external data structures */
/* ====================================================== function prototypes */
} // namespace Core
} // namespace LiveSupport
#endif // LiveSupport_Core_FileTools_h

View file

@ -0,0 +1,146 @@
/*------------------------------------------------------------------------------
Copyright (c) 2004 Media Development Loan Fund
This file is part of the LiveSupport project.
http://livesupport.campware.org/
To report bugs, send an e-mail to bugs@campware.org
LiveSupport is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
LiveSupport is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with LiveSupport; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Author : $Author: fgerlits $
Version : $Revision$
Location : $URL: svn+ssh://fgerlits@code.campware.org/home/svn/repo/livesupport/trunk/livesupport/src/modules/core/src/FileTools.cxx $
------------------------------------------------------------------------------*/
/* ============================================================ include files */
#ifdef HAVE_CONFIG_H
#include "configure.h"
#endif
#ifdef HAVE_TIME_H
#include <time.h>
#else
#error need time.h
#endif
#include <fstream>
#include <curl/curl.h>
#include <curl/easy.h>
#include "LiveSupport/Core/FileTools.h"
using namespace LiveSupport;
using namespace LiveSupport::Core;
/* =================================================== local data structures */
/* ================================================ local constants & macros */
/* =============================================== local function prototypes */
/* ============================================================= module code */
/*------------------------------------------------------------------------------
* Copy the contents of a URL to a local file.
*----------------------------------------------------------------------------*/
void
FileTools :: copyUrlToFile(const std::string & url,
const std::string & path)
throw (std::runtime_error)
{
FILE* file = fopen(path.c_str(), "wb");
if (!file) {
throw std::runtime_error("File location is not writable.");
}
CURL* handle = curl_easy_init();
if (!handle) {
fclose(file);
throw std::runtime_error("Could not obtain curl handle.");
}
int status = curl_easy_setopt(handle, CURLOPT_URL, url.c_str());
status |= curl_easy_setopt(handle, CURLOPT_WRITEDATA, file);
status |= curl_easy_setopt(handle, CURLOPT_HTTPGET);
if (status) {
fclose(file);
throw std::runtime_error("Could not set curl options.");
}
status = curl_easy_perform(handle);
if (status) {
fclose(file);
throw std::runtime_error("Error downloading file.");
}
curl_easy_cleanup(handle);
fclose(file);
}
/*------------------------------------------------------------------------------
* Upload the contents of a local file to a writable URL.
*----------------------------------------------------------------------------*/
void
FileTools :: copyFileToUrl(const std::string & path,
const std::string & url)
throw (std::runtime_error)
{
FILE* file = fopen(path.c_str(), "rb");
if (!file) {
throw std::runtime_error("File not found.");
}
fseek(file, 0, SEEK_END);
long fileSize = ftell(file);
rewind(file);
CURL* handle = curl_easy_init();
if (!handle) {
throw std::runtime_error("Could not obtain curl handle.");
}
int status = curl_easy_setopt(handle, CURLOPT_READDATA, file);
status |= curl_easy_setopt(handle, CURLOPT_INFILESIZE, fileSize);
// works for files of size up to 2 GB
status |= curl_easy_setopt(handle, CURLOPT_PUT, 1);
status |= curl_easy_setopt(handle, CURLOPT_URL, url.c_str());
// status |= curl_easy_setopt(handle, CURLOPT_HEADER, 1);
// status |= curl_easy_setopt(handle, CURLOPT_ENCODING, "deflate");
if (status) {
throw std::runtime_error("Could not set curl options.");
}
status = curl_easy_perform(handle);
if (status) {
throw std::runtime_error("Error uploading file.");
}
curl_easy_cleanup(handle);
fclose(file);
}

View file

@ -40,12 +40,9 @@
#endif
#include <iostream>
#include <fstream>
#include <boost/date_time/posix_time/posix_time.hpp>
#include <XmlRpcClient.h>
#include <XmlRpcUtil.h>
#include <curl/curl.h>
#include <curl/easy.h>
#include "LiveSupport/Core/Md5.h"
#include "LiveSupport/Core/XmlRpcCommunicationException.h"
@ -55,6 +52,8 @@
#include "LiveSupport/Core/XmlRpcIOException.h"
#include "LiveSupport/Core/XmlRpcInvalidDataException.h"
#include "LiveSupport/Core/TimeConversion.h"
#include "LiveSupport/Core/FileTools.h"
#include "WebStorageClient.h"
using namespace boost::posix_time;
@ -1901,39 +1900,12 @@ WebStorageClient :: storeAudioClip(Ptr<SessionId>::Ref sessionId,
std::string url = std::string(result[storeAudioClipUrlParamName]);
std::string token = std::string(result[storeAudioClipTokenParamName]);
FILE* binaryFile = fopen(binaryFileName.c_str(), "rb");
if (!binaryFile) {
throw XmlRpcIOException("Binary audio clip file not found.");
try {
FileTools::copyFileToUrl(binaryFileName, url);
} catch (std::runtime_error &e) {
throw XmlRpcCommunicationException(e.what());
}
fseek(binaryFile, 0, SEEK_END);
long binaryFileSize = ftell(binaryFile);
rewind(binaryFile);
CURL* handle = curl_easy_init();
if (!handle) {
throw XmlRpcCommunicationException("Could not obtain curl handle.");
}
int status = curl_easy_setopt(handle, CURLOPT_READDATA, binaryFile);
status |= curl_easy_setopt(handle, CURLOPT_INFILESIZE, binaryFileSize);
// works for files of size up to 2 GB
status |= curl_easy_setopt(handle, CURLOPT_PUT, 1);
status |= curl_easy_setopt(handle, CURLOPT_URL, url.c_str());
// status |= curl_easy_setopt(handle, CURLOPT_HEADER, 1);
// status |= curl_easy_setopt(handle, CURLOPT_ENCODING, "deflate");
if (status) {
throw XmlRpcCommunicationException("Could not set curl options.");
}
status = curl_easy_perform(handle);
if (status) {
throw XmlRpcCommunicationException("Error uploading file.");
}
curl_easy_cleanup(handle);
fclose(binaryFile);
parameters.clear();
parameters[storeAudioClipSessionIdParamName]
@ -2571,37 +2543,12 @@ WebStorageClient :: importPlaylist(
std::string url = std::string(result[importPlaylistUrlParamName]);
std::string token = std::string(result[importPlaylistTokenParamName]);
FILE* binaryFile = fopen(path->c_str(), "rb");
if (!binaryFile) {
throw XmlRpcIOException("The playlist archive file disappeared.");
try {
FileTools::copyFileToUrl(*path, url);
} catch (std::runtime_error &e) {
throw XmlRpcCommunicationException(e.what());
}
fseek(binaryFile, 0, SEEK_END);
long binaryFileSize = ftell(binaryFile);
rewind(binaryFile);
CURL* handle = curl_easy_init();
if (!handle) {
throw XmlRpcCommunicationException("Could not obtain curl handle.");
}
int status = curl_easy_setopt(handle, CURLOPT_READDATA, binaryFile);
status |= curl_easy_setopt(handle, CURLOPT_INFILESIZE, binaryFileSize);
// works for files of size up to 2 GB
status |= curl_easy_setopt(handle, CURLOPT_PUT, 1);
status |= curl_easy_setopt(handle, CURLOPT_URL, url.c_str());
if (status) {
throw XmlRpcCommunicationException("Could not set curl options.");
}
status = curl_easy_perform(handle);
if (status) {
throw XmlRpcCommunicationException("Error uploading file.");
}
curl_easy_cleanup(handle);
fclose(binaryFile);
parameters.clear();
parameters[importPlaylistTokenParamName]

View file

@ -39,12 +39,12 @@
#error need pwd.h
#endif
#include <curl/curl.h>
#include <curl/easy.h>
#include <gtkmm/filechooserdialog.h>
#include <gtkmm/stock.h>
#include <gtkmm/paned.h>
#include "LiveSupport/Core/FileTools.h"
#include "BackupView.h"
@ -341,47 +341,12 @@ BackupView :: onSaveButtonClicked(void) throw ()
}
fileName->assign(dialog->get_filename());
copyUrlToFile(url, fileName);
}
try {
FileTools::copyUrlToFile(*url, *fileName);
/*------------------------------------------------------------------------------
* Fetch the backup file from an URL and save it to a local file.
*----------------------------------------------------------------------------*/
bool
BackupView :: copyUrlToFile(Ptr<Glib::ustring>::Ref url,
Ptr<Glib::ustring>::Ref fileName) throw ()
{
FILE* localFile = fopen(fileName->c_str(), "wb");
if (!localFile) {
return false;
} catch (std::runtime_error &e) {
// TODO: handle error
}
CURL* handle = curl_easy_init();
if (!handle) {
fclose(localFile);
return false;
}
int status = curl_easy_setopt(handle, CURLOPT_URL, url->c_str());
status |= curl_easy_setopt(handle, CURLOPT_WRITEDATA, localFile);
status |= curl_easy_setopt(handle, CURLOPT_HTTPGET);
if (status) {
fclose(localFile);
return false;
}
status = curl_easy_perform(handle);
if (status) {
fclose(localFile);
return false;
}
curl_easy_cleanup(handle);
fclose(localFile);
return true;
}

View file

@ -139,17 +139,6 @@ class BackupView : public Gtk::VBox,
Gtk::Box *
constructBackupListView(void) throw ();
/**
* Fetch the backup file from an URL and save it to a local file.
*
* @param url the URL to fetch.
* @param fileName the local file to save as.
* @return the status reported by curl (true if everything is OK).
*/
bool
copyUrlToFile(Ptr<Glib::ustring>::Ref url,
Ptr<Glib::ustring>::Ref fileName) throw ();
/**
* Read the title of the backup from the entry field.
* If the entry is blank, a default title is used.

View file

@ -39,11 +39,10 @@
#error need pwd.h
#endif
#include <curl/curl.h>
#include <curl/easy.h>
#include <gtkmm/filechooserdialog.h>
#include <gtkmm/stock.h>
#include "LiveSupport/Core/FileTools.h"
#include "LiveSupport/Widgets/WidgetFactory.h"
#include "ExportPlaylistWindow.h"
@ -215,8 +214,10 @@ ExportPlaylistWindow :: onSaveButtonClicked(void) throw ()
// save the exported playlist as a local file
if (result == Gtk::RESPONSE_OK) {
fileName->assign(dialog->get_filename());
bool success = copyUrlToFile(url, fileName);
if (!success) {
try {
FileTools::copyUrlToFile(*url, *fileName);
} catch (std::runtime_error &e) {
Ptr<Glib::ustring>::Ref errorMsg = getResourceUstring(
"saveExportErrorMsg");
gLiveSupport->displayMessageWindow(errorMsg);
@ -230,47 +231,6 @@ ExportPlaylistWindow :: onSaveButtonClicked(void) throw ()
}
/*------------------------------------------------------------------------------
* Fetch the exported playlist from a URL and save it to a local file.
*----------------------------------------------------------------------------*/
bool
ExportPlaylistWindow :: copyUrlToFile(Ptr<Glib::ustring>::Ref url,
Ptr<Glib::ustring>::Ref fileName)
throw ()
{
FILE* localFile = fopen(fileName->c_str(), "wb");
if (!localFile) {
return false;
}
CURL* handle = curl_easy_init();
if (!handle) {
fclose(localFile);
return false;
}
int status = curl_easy_setopt(handle, CURLOPT_URL, url->c_str());
status |= curl_easy_setopt(handle, CURLOPT_WRITEDATA, localFile);
status |= curl_easy_setopt(handle, CURLOPT_HTTPGET);
if (status) {
fclose(localFile);
return false;
}
status = curl_easy_perform(handle);
if (status) {
fclose(localFile);
return false;
}
curl_easy_cleanup(handle);
fclose(localFile);
return true;
}
/*------------------------------------------------------------------------------
* Event handler called when the the window gets hidden.
*----------------------------------------------------------------------------*/

View file

@ -86,17 +86,6 @@ class ExportPlaylistWindow : public GuiWindow
*/
ExportFormatRadioButtons * formatButtons;
/**
* Fetch the exported playlist from a URL and save it to a local file.
*
* @param url the URL to fetch.
* @param fileName the local file to save as.
* @return the status reported by curl (true if everything is OK).
*/
bool
copyUrlToFile(Ptr<Glib::ustring>::Ref url,
Ptr<Glib::ustring>::Ref fileName) throw ();
/**
* Cancel the current operation.
* Call exportPlaylistClose() on token, and reset it to 0.