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

RemoteRetriever.h

Go to the documentation of this file.
00001 #ifndef REMOTERETRIEVER_H
00002 #define REMOTERETRIEVER_H
00003 
00004 // Todo: MD5 Hash of filename for cache?
00005 
00006 #ifdef USE_CURL
00007 #include "curl/curl.h"
00008 #endif
00009 
00010 #ifdef USE_BOOST_THREADPOOL
00011 #define USE_BOOST_THREAD
00012 #include "boost/thread/mutex.hpp"
00013 #endif
00014 
00015 #include <sys/stat.h>
00016 #include <iostream>
00017 #include <fstream>
00018 
00019 #include "Core/Array/ReadImage.h"
00020 
00021 namespace Impala { namespace Application { namespace MediaTable {
00022 
00023 typedef Core::Array::Array2dVec3UInt8   Array2dVec3UInt8;
00024 
00025 class RemoteRetriever {
00026 public:
00027     static RemoteRetriever* GetInstance() {
00028         if (!sInstance)
00029         {
00030             ILOG_INFO("Instantiating RemoteRetriever.");
00031             sInstance = new RemoteRetriever();
00032         }
00033         return sInstance;
00034     }
00035 
00036         Array2dVec3UInt8* RetrieveImageData(std::string url, bool fromCache=true, bool toCache=true) {
00037                 if(!mUseCache) fromCache = toCache = false;
00038 
00039                 Array2dVec3UInt8* imageData = 0;
00040 
00041 #ifndef WIN32
00042                 if((toCache || fromCache) && !FileExists(mCachePrefix))
00043                 {
00044                         ILOG_WARN("Cache folder does not exists, continuing without cache");
00045                         toCache = fromCache = false;
00046                 }
00047 #endif
00048 
00049                 std::string filename = mCachePrefix + url.substr(url.find_last_of('/')+1);
00050         RemoteFileRetriever retriever = RemoteFileRetriever(url, fromCache, toCache, filename);
00051                 retriever();
00052 
00053                 if(retriever.target.size() < 512)
00054                 {
00055                         ILOG_ERROR("Image is smaller than 512 bytes, skipping.");
00056                         return 0;
00057                 }
00058 
00059                 ILOG_DEBUG("Trying to ReadJpg from " << &retriever.target << " with size " << retriever.target.size());
00060 #ifdef USE_BOOST_THREAD
00061                 {
00062                         boost::mutex::scoped_lock lock(mutex_readjpg);
00063                         Core::Array::ReadJpgFromMemory(imageData, (char*) retriever.target.c_str(), retriever.target.size());
00064                 }
00065 #else
00066                 Core::Array::ReadJpgFromMemory(imageData, (char*) retriever.target.c_str(), retriever.target.size());
00067 #endif
00068 
00069                 if(imageData != 0)
00070                         ILOG_DEBUG("Returning image data of " << imageData->CW() << "x" << imageData->CH() <<" pixels at " << imageData);
00071         return imageData;
00072     }
00073 
00074         std::string RetrieveFile(std::string url, bool fromCache=true, bool toCache=true, std::string filename = "") {
00075                 if(filename == "" || !mUseCache) fromCache = toCache = false;
00076         RemoteFileRetriever retriever = RemoteFileRetriever(url, fromCache, toCache, filename);
00077         retriever();
00078         return filename;
00079     }
00080 
00081         class RemoteFileRetriever {
00082         public:
00083                 RemoteFileRetriever(std::string url, bool fromCache, bool toCache, std::string filename = "") :
00084                         url(url), fromCache(fromCache), toCache(toCache), filename(filename) {
00085                         target = std::string();
00086                 }
00087                 RemoteFileRetriever(std::string url, std::string &target, bool fromCache, bool toCache, std::string filename = "") :
00088                         url(url), fromCache(fromCache), toCache(toCache), filename(filename), target(target) {
00089                 }
00090 
00091                 int operator()() {
00092                         ILOG_DEBUG("Getting file from: " << url << " to store in " << &target);
00093 
00094                         Core::Array::Array2dVec3UInt8* im = 0;
00095                         if(fromCache && FileExists(filename)) {
00096                                 ILOG_DEBUG("Retrieving file from " << filename);
00097                                 std::ifstream cachedFile(filename.c_str(), std::ios::binary | std::ios::in);
00098                                 while (cachedFile.good())     // loop while extraction from file is possible
00099                                     target += (char) cachedFile.get();       // get character from file
00100                                 cachedFile.close();
00101                                 return 1;
00102                         }
00103 
00104 #ifdef USE_CURL
00105                         CURL *h = curl_easy_init();
00106                         CURLcode result;
00107 
00108                         target = std::string();
00109 
00110                         curl_easy_setopt(h, CURLOPT_URL, url.c_str());
00111                         curl_easy_setopt(h, CURLOPT_WRITEFUNCTION, CurlCallback);
00112                         curl_easy_setopt(h, CURLOPT_WRITEDATA, &target);
00113 #ifdef WIN32
00114                         curl_easy_setopt(h, CURLOPT_TIMEOUT, 5);
00115 #endif
00116 
00117                         ILOG_DEBUG("Retrieving remote: " << url);
00118                         result = curl_easy_perform(h);
00119 
00120                         if (result == CURLE_OK) {
00121                                 ILOG_DEBUG("retrieved " << target.size() << ", trying decode...");
00122 
00123                                 if(toCache) {
00124 #ifdef USE_BOOST_THREAD
00125                                         boost::mutex::scoped_lock lock(RemoteRetriever::GetInstance()->mutex_cache);
00126 #endif
00127                                         std::ofstream cachedFile(filename.c_str(), std::ios::binary | std::ios::out);
00128                                         cachedFile << target;
00129                                         cachedFile.close();
00130                                 } else {
00131                                 }
00132                                 curl_easy_cleanup(h);
00133                                 return 1;
00134                         }
00135                         curl_easy_cleanup(h);
00136                         ILOG_ERROR("Could not retrieve URI: " << url);
00137                         return 0;
00138 #else
00139                         ILOG_ERROR("Network retrieval of files not compiled in this version.");
00140                         return 0;
00141 #endif
00142                 }
00143 
00144                 bool FileExists(std::string strFilename) {
00145                         struct stat stFileInfo;
00146                         int intStat = stat(strFilename.c_str(),&stFileInfo);
00147                         if(intStat == 0) return true;
00148                         return false;
00149                 }
00150 
00151 #ifdef USE_CURL
00152                 static size_t CurlCallback(char *data, size_t size, size_t nmemb, std::string *buffer) {
00153                                 if (buffer != 0) {
00154                                         buffer->append(data, size * nmemb);
00155                                 } else return 0;
00156                                 return size * nmemb;
00157                 }
00158 #endif
00159 
00160                 std::string url, filename, target;
00161                 bool toCache, fromCache;
00162         };
00163 
00164 private:
00165         RemoteRetriever(std::string cachePrefix = "Cache/") // constructor: private
00166         {
00167 
00168 #ifdef USE_CURL
00169                 if (!sCurlInit) {
00170                         ILOG_DEBUG("Initializing CURL...");
00171                         // Only does something on Windows
00172                         curl_global_init(CURL_GLOBAL_WIN32);
00173                         sCurlInit = true;
00174                 }
00175 #endif
00176 
00177                 mCachePrefix = cachePrefix;
00178                 //if(FileExists(mCachePrefix))
00179                 mUseCache = true;
00180                 //else
00181                 //      ILOG_WARN("Cache folder does not exists, continuing without cache");
00182         }
00183 
00184         RemoteRetriever(RemoteRetriever const&){};             // copy constructor: private
00185         RemoteRetriever& operator=(RemoteRetriever const&){};  // assignment operator: private
00186 
00187         bool                                                     mUseCache;
00188         std::string                                              mCachePrefix;
00189 
00190         static RemoteRetriever*          sInstance;
00191 
00192 #ifdef USE_CURL
00193         static bool                                              sCurlInit;
00194 #endif
00195 
00196 #ifdef USE_BOOST_THREAD
00197         boost::mutex                    mutex_readjpg;
00198 public:
00199         boost::mutex                    mutex_cache;
00200 private:
00201 #endif
00202 
00203     ILOG_VAR_DEC;
00204 };
00205 
00206 RemoteRetriever* RemoteRetriever::sInstance = 0;
00207 
00208 #ifdef USE_CURL
00209 bool RemoteRetriever::sCurlInit = false;
00210 #endif
00211 
00212 ILOG_VAR_INIT(RemoteRetriever, Application.MediaTable);
00213 
00214 } } } // Namespace Impala::Application::MediaTable
00215 
00216 #endif // REMOTERETRIEVER_H

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