Home || Architecture || Video Search || Visual Search || Scripts || Applications || Important Messages || OGL || Src

RemoteRetriever.h

Go to the documentation of this file.
00001 #ifndef Impala_Application_TagsLife_RemoteRetriever_h
00002 #define Impala_Application_TagsLife_RemoteRetriever_h
00003 
00004 #ifdef USE_CURL
00005 //#include "Link/curl/curl.h"
00006 #include "curl/curl.h"
00007 #endif
00008 
00009 #include <sys/stat.h>
00010 #include <iostream>
00011 #include <fstream>
00012 
00013 #ifdef USE_BOOST_THREAD
00014 #ifndef USE_BOOST_THREADPOOL
00015 #include <boost/thread/thread.hpp>
00016 #endif
00017 #endif
00018 
00019 #ifdef USE_BOOST_THREADPOOL
00020 #define USE_BOOST_THREAD
00021 // use this version for boost v. 34 (as on UvA FC8)
00022 //#include "threadpool23/threadpool.hpp"
00023 // use this version for boost >= 37 (as on decent machines)
00024 #include "threadpool25/threadpool.hpp"
00025 using namespace boost::threadpool;
00026 #endif
00027 
00028 #include "Visualization/RgbOglImage.h"
00029 #include "Core/Array/ReadImage.h"
00030 
00031 namespace Impala {
00032 namespace Application {
00033 namespace TagsLife {
00034 
00035 class RemoteRetriever {
00036 public:
00037     static RemoteRetriever* GetInstance() {
00038         if (!sInstance)
00039         {
00040             ILOG_INFO("Instantiating RemoteRetriever.");
00041             sInstance = new RemoteRetriever();
00042         }
00043         return sInstance;
00044     }
00045 
00046         /* requestImage returns an OGLIMAGE* that is either the resulting image or
00047          * if USE_BOOST_THREAD is defined an empty image of 0x0.
00048          *
00049          * This empty image will be initialized in a thread and with either the correct data or
00050          * with w = h = -1 in case of an error.
00051          */
00052         OGLIMAGE* requestImage(std::string url, bool fromCache=true, bool toCache=true) {
00053         Core::Array::Array2dVec3UInt8* empty = Core::Array::ArrayCreate<Core::Array::Array2dVec3UInt8>(0, 0, 0, 0);
00054         OGLIMAGE* oglIm = Visualization::RgbOglImage::OglImage(empty);
00055                 if(!mUseCache) fromCache = toCache = false;
00056         RemoteImageRetriever retriever = RemoteImageRetriever(url, oglIm, fromCache, toCache, mCachePrefix);
00057 #ifdef USE_BOOST_THREAD
00058 #ifdef USE_BOOST_THREADPOOL
00059         threadpool.schedule(retriever);
00060 #else
00061         boost::thread work(retriever);
00062 #endif
00063 #else
00064         retriever();
00065 #endif
00066                 ILOG_DEBUG("Returning image of " << oglIm->w << "x" << oglIm->h <<" pixels at " << oglIm);
00067         return oglIm;
00068     }
00069 
00070         std::string requestFile(std::string url, bool fromCache=true, bool toCache=true, std::string filename = "") {
00071                 //if(filename == "" || !mUseCache) fromCache = toCache = false;
00072         RemoteFileRetriever retriever = RemoteFileRetriever(url, fromCache, toCache, filename);
00073 #ifdef USE_BOOST_THREAD
00074 #ifdef USE_BOOST_THREADPOOL
00075         threadpool.schedule(retriever);
00076 #else
00077         boost::thread work(retriever);
00078 #endif
00079 #else
00080         retriever();
00081 #endif
00082         return filename;
00083     }
00084 
00085         class RemoteFileRetriever {
00086         public:
00087                 RemoteFileRetriever(std::string url, bool fromCache, bool toCache, std::string filename = "") :
00088                         url(url), fromCache(fromCache), toCache(toCache), filename(filename) {
00089                         target = std::string();
00090                 }
00091                 RemoteFileRetriever(std::string url, std::string &target, bool fromCache, bool toCache, std::string filename = "") :
00092                         url(url), fromCache(fromCache), toCache(toCache), filename(filename), target(target) {
00093                 }
00094 
00095                 int operator()() {
00096                         ILOG_DEBUG("Getting file from: " << url << " to store in " << target);
00097 
00098                         Core::Array::Array2dVec3UInt8* im = 0;
00099                         if(fromCache && FileExists(filename)) {
00100                                 ILOG_DEBUG("Retrieving file from " << filename);
00101                                 std::ifstream cachedFile(filename.c_str(), std::ios::binary | std::ios::in);
00102                                 while (cachedFile.good())     // loop while extraction from file is possible
00103                                     target += (char) cachedFile.get();       // get character from file
00104                                 cachedFile.close();
00105                                 return 1;
00106                         }
00107 
00108 #ifdef USE_CURL
00109                         CURL *h = curl_easy_init();
00110                         CURLcode result;
00111 
00112                         target = std::string();
00113 
00114                         curl_easy_setopt(h, CURLOPT_URL, url.c_str());
00115                         curl_easy_setopt(h, CURLOPT_WRITEFUNCTION, CurlCallback);
00116                         curl_easy_setopt(h, CURLOPT_WRITEDATA, &target);
00117 
00118                         ILOG_DEBUG("Retrieving remote: " << url);
00119                         result = curl_easy_perform(h);
00120 
00121                         if (result == CURLE_OK) {
00122                                 ILOG_DEBUG("retrieved " << target.size() << ", trying decode...");
00123 
00124                                 if(toCache) {
00125                                         std::ofstream cachedFile(filename.c_str(), std::ios::binary | std::ios::out);
00126                                         cachedFile << target;
00127                                         cachedFile.close();
00128                                 } else {
00129                                 }
00130                                 curl_easy_cleanup(h);
00131                                 return 1;
00132                         }
00133                         curl_easy_cleanup(h);
00134                         ILOG_ERROR("Could not retrieve URI: " << url);
00135                         return 0;
00136 #else
00137                         ILOG_ERROR("Network retrieval of files not compiled in this version.");
00138                         return 0;
00139 #endif
00140                 }
00141 
00142                 bool FileExists(std::string strFilename) {
00143                         struct stat stFileInfo;
00144                         int intStat = stat(strFilename.c_str(),&stFileInfo);
00145                         if(intStat == 0) return true;
00146                         return false;
00147                 }
00148 
00149 #ifdef USE_CURL
00150                 static size_t CurlCallback(char *data, size_t size, size_t nmemb, std::string *buffer) {
00151                                 if (buffer != 0) {
00152                                         buffer->append(data, size * nmemb);
00153                                 } else return 0;
00154                                 return size * nmemb;
00155                 }
00156 #endif
00157 
00158                 std::string url, filename, target;
00159                 bool toCache, fromCache;
00160         };
00161 
00162         class RemoteImageRetriever : RemoteFileRetriever {
00163         public:
00164                 RemoteImageRetriever(std::string &url, OGLIMAGE* &oglIm, bool fromCache, bool toCache, std::string cachePrefix) :
00165                         oglIm(oglIm), RemoteFileRetriever(url, fromCache, toCache) {
00166                         filename = cachePrefix + url.substr(url.find_last_of('/')+1);
00167                 }
00168 
00169                 int operator()() {
00170                         ILOG_DEBUG("Getting Image from: " << url << " to store in " << target);
00171 
00172                         if((toCache || fromCache) && !FileExists("Cache")) {
00173                                 ILOG_WARN("Cache folder does not exists, continuing without cache");
00174                                 toCache = fromCache = false;
00175                         }
00176 
00177                         Core::Array::Array2dVec3UInt8* im = 0;
00178 
00179                         RemoteFileRetriever::operator()();
00180 
00181                         Core::Array::ReadJpgFromMemory(im, (char*) target.c_str(), target.size());
00182                         if(im != 0) {
00183                                 oglIm->imageHandle = im;
00184                                 oglIm->h = im->CH();
00185                                 oglIm->w = im->CW();
00186                                 oglIm->changed = 1;
00187                                 ILOG_DEBUG("Loaded an image of " << oglIm->w << "x" << oglIm->h <<" pixels to " << oglIm << " from " << url);
00188                                 return 1;
00189                         }
00190 
00191                         ILOG_ERROR("Failed to load image from " << url << "! (buffer.size = " << target.size() << ")");
00192 
00193                         oglIm->h = -1;
00194                         oglIm->w = -1;
00195                         oglIm->changed = 1;
00196                         return 0;
00197                 }
00198 
00199                 OGLIMAGE* oglIm;
00200         };
00201 
00202 private:
00203         RemoteRetriever(std::string cachePrefix = "Cache/") // constructor: private
00204         {
00205 
00206 #ifdef USE_CURL
00207                 if (!sCurlInit) {
00208                         ILOG_DEBUG("Initializing CURL...");
00209                         // Only does something on Windows
00210                         curl_global_init(CURL_GLOBAL_WIN32);
00211                         sCurlInit = true;
00212                 }
00213 #endif
00214 
00215 #ifdef USE_BOOST_THREADPOOL
00216                 threadpool = pool(8);
00217 #endif
00218                 mCachePrefix = cachePrefix;
00219                 //if(FileExists(mCachePrefix))
00220                 mUseCache = true;
00221                 //else
00222                 //      ILOG_WARN("Cache folder does not exists, continuing without cache");
00223         }
00224 
00225         RemoteRetriever(RemoteRetriever const&){};             // copy constructor: private
00226         RemoteRetriever& operator=(RemoteRetriever const&){};  // assignment operator: private
00227 
00228         bool                                                     mUseCache;
00229         std::string                                              mCachePrefix;
00230 
00231         static RemoteRetriever*          sInstance;
00232 
00233 #ifdef USE_CURL
00234         static bool sCurlInit;
00235 #endif
00236 
00237 #ifdef USE_BOOST_THREADPOOL
00238         pool threadpool;
00239 #endif
00240 
00241     ILOG_VAR_DEC;
00242 };
00243 
00244 RemoteRetriever* RemoteRetriever::sInstance = 0;
00245 
00246 #ifdef USE_CURL
00247 bool RemoteRetriever::sCurlInit = false;
00248 #endif
00249 
00250 ILOG_VAR_INIT(RemoteRetriever, Application.TagsLife);
00251 
00252 }
00253 }
00254 }
00255 
00256 #endif // Impala_Application_TagsLife_RemoteRetriever_h

Generated on Fri Mar 19 09:30:33 2010 for ImpalaSrc by  doxygen 1.5.1