diff --git a/lutin_zeus.py b/lutin_zeus.py index edfef84..a593c21 100644 --- a/lutin_zeus.py +++ b/lutin_zeus.py @@ -42,11 +42,13 @@ def configure(target, my_module): 'zeus/FutureBase.cpp', 'zeus/Future.cpp', 'zeus/Promise.cpp', + 'zeus/FutureGroup.cpp', ]) my_module.add_header_file([ 'zeus/Promise.hpp', 'zeus/FutureBase.hpp', 'zeus/Future.hpp', + 'zeus/FutureGroup.hpp', ]) # messaging interface diff --git a/test/client/appl/main-test-client.cpp b/test/client/appl/main-test-client.cpp index 1ba9506..2163511 100644 --- a/test/client/appl/main-test-client.cpp +++ b/test/client/appl/main-test-client.cpp @@ -17,9 +17,11 @@ #include #include #include +#include #include #include #include +#include void installPath(zeus::service::ProxyPicture& _srv, std::string _path, uint32_t _albumID) { etk::FSNode node(_path); @@ -67,6 +69,149 @@ void installPath(zeus::service::ProxyPicture& _srv, std::string _path, uint32_t } +void installVideoPath(zeus::service::ProxyVideo& _srv, std::string _path, std::map _basicKey = std::map()) { + etk::FSNode node(_path); + APPL_INFO("Parse : '" << _path << "'"); + std::vector listSubPath = node.folderGetSub(true, false, "*"); + for (auto &itPath : listSubPath) { + std::map basicKeyTmp = _basicKey; + APPL_INFO("Add Sub path: '" << itPath << "'"); + std::string lastPathName = etk::split(itPath, '/').back(); + if (basicKeyTmp.size() == 0) { + APPL_INFO("find '" << lastPathName << "' " << basicKeyTmp.size()); + if (lastPathName == "films") { + basicKeyTmp.insert(std::pair("type", "film")); + basicKeyTmp.insert(std::pair("production-methode", "picture")); + } else if (lastPathName == "films-annimation") { + basicKeyTmp.insert(std::pair("type", "film")); + basicKeyTmp.insert(std::pair("production-methode", "draw")); + } else if (lastPathName == "tv-show") { + basicKeyTmp.insert(std::pair("type", "tv-show")); + basicKeyTmp.insert(std::pair("production-methode", "picture")); + } else if (lastPathName == "anim") { + basicKeyTmp.insert(std::pair("type", "tv-show")); + basicKeyTmp.insert(std::pair("production-methode", "draw")); + } else if (lastPathName == "courses") { // short films + basicKeyTmp.insert(std::pair("type", "courses")); + basicKeyTmp.insert(std::pair("production-methode", "picture")); // TODO : Check "draw" + } else if (lastPathName == "theater") { + basicKeyTmp.insert(std::pair("type", "theater")); + basicKeyTmp.insert(std::pair("production-methode", "picture")); + } else if (lastPathName == "one-man-show") { + basicKeyTmp.insert(std::pair("type", "one-man show")); + basicKeyTmp.insert(std::pair("production-methode", "picture")); + } + } else { + APPL_INFO("find '" << lastPathName << "' " << basicKeyTmp.size()); + if (lastPathName == "saison_01") { + basicKeyTmp.insert(std::pair("saison", "1")); + } else if (lastPathName == "saison_02") { + basicKeyTmp.insert(std::pair("saison", "2")); + } else if (lastPathName == "saison_03") { + basicKeyTmp.insert(std::pair("saison", "3")); + } else if (lastPathName == "saison_04") { + basicKeyTmp.insert(std::pair("saison", "4")); + } else if (lastPathName == "saison_05") { + basicKeyTmp.insert(std::pair("saison", "5")); + } else if (lastPathName == "saison_06") { + basicKeyTmp.insert(std::pair("saison", "6")); + } else if (lastPathName == "saison_07") { + basicKeyTmp.insert(std::pair("saison", "7")); + } else if (lastPathName == "saison_08") { + basicKeyTmp.insert(std::pair("saison", "8")); + } else if (lastPathName == "saison_09") { + basicKeyTmp.insert(std::pair("saison", "9")); + } else if (lastPathName == "saison_10") { + basicKeyTmp.insert(std::pair("saison", "10")); + } else if (lastPathName == "saison_11") { + basicKeyTmp.insert(std::pair("saison", "11")); + } else if (lastPathName == "saison_12") { + basicKeyTmp.insert(std::pair("saison", "12")); + } else if (lastPathName == "saison_13") { + basicKeyTmp.insert(std::pair("saison", "13")); + } else if (lastPathName == "saison_14") { + basicKeyTmp.insert(std::pair("saison", "14")); + } else if (lastPathName == "saison_15") { + basicKeyTmp.insert(std::pair("saison", "15")); + } else if (lastPathName == "saison_16") { + basicKeyTmp.insert(std::pair("saison", "16")); + } else if (lastPathName == "saison_17") { + basicKeyTmp.insert(std::pair("saison", "17")); + } else if (lastPathName == "saison_18") { + basicKeyTmp.insert(std::pair("saison", "18")); + } else if (lastPathName == "saison_19") { + basicKeyTmp.insert(std::pair("saison", "19")); + } else if (lastPathName == "saison_20") { + basicKeyTmp.insert(std::pair("saison", "20")); + } else { + basicKeyTmp.insert(std::pair("series-name", lastPathName)); + } + } + installVideoPath(_srv, itPath, basicKeyTmp); + } + // Add files : + std::vector listSubFile = node.folderGetSub(false, true, "*"); + for (auto &itFile : listSubFile) { + std::map basicKeyTmp = _basicKey; + APPL_INFO("Add media : '" << itFile << "'"); + std::string extention = etk::tolower(std::string(itFile.begin()+itFile.size() -3, itFile.end())); + if ( extention == "avi" + || extention == "mkv" + || extention == "mov" + || extention == "mp4") { + + uint32_t mediaId = _srv.mediaAdd(zeus::File::create(itFile)).wait().get(); + if (mediaId == 0) { + APPL_ERROR("Get media ID = 0 With no error"); + continue; + } + + // Parse file name: + std::vector listElement = etk::split(itFile, '-'); + if (listElement.size() == 1) { + // nothing to do , it might be a film ... + } else { + if ( listElement.size() > 3 + && listElement[1][0] == 's' + && listElement[2][0] == 'e') { + // internal formalisme ... + int32_t saison = -1; + int32_t episode = -1; + std::string seriesName = listElement[0]; + if (std::string(&listElement[1][1]) == "XX") { + // saison unknow ... ==> nothing to do ... + } else { + saison = etk::string_to_int32_t(&listElement[1][1]); + } + if (std::string(&listElement[2][1]) == "XX") { + // episode unknow ... ==> nothing to do ... + } else { + episode = etk::string_to_int32_t(&listElement[2][1]); + + basicKeyTmp.insert(std::pair("episode", etk::to_string(episode))); + } + APPL_INFO("Find a internal mode series: :"); + APPL_INFO(" origin : '" << listElement << "'"); + APPL_INFO(" recontituated: '" << seriesName << "'-s" << saison << "-e" << episode << "-" << &listElement[3][1]); + // TODO: try to find the date of the media: "(XXXX)" + + // TODO: try to find main actor in the media: "[XXX][YYY]" + + } + } + + // send all meta data: + zeus::FutureGroup group; + for (auto &itKey : _basicKey) { + group.add(_srv.mediaMetadataSetKey(mediaId, itKey.first, itKey.second)); + } + group.wait(); + + } else { + APPL_ERROR("Sot send file : " << itFile << " Not manage extention..."); + } + } +} int main(int _argc, const char *_argv[]) { etk::init(_argc, _argv); elog::init(_argc, _argv); @@ -187,7 +332,7 @@ int main(int _argc, const char *_argv[]) { APPL_INFO(" ----------------------------------"); APPL_INFO(" -- Get service picture"); APPL_INFO(" ----------------------------------"); - if (true) { + if (false) { zeus::service::ProxyPicture remoteServicePicture = client1.getService("picture"); if (remoteServicePicture.exist() == true) { // Send a full path: @@ -196,7 +341,7 @@ int main(int _argc, const char *_argv[]) { APPL_ERROR("Can not get service Picture ..."); } } - if (true) { + if (false) { zeus::service::ProxyPicture remoteServicePicture = client1.getService("picture"); if (remoteServicePicture.exist() == true) { zeus::Future> retCall = remoteServicePicture.albumGetList().wait(); @@ -243,6 +388,26 @@ int main(int _argc, const char *_argv[]) { #endif } } + APPL_INFO(" ----------------------------------"); + APPL_INFO(" -- Get service video"); + APPL_INFO(" ----------------------------------"); + if (true) { + zeus::service::ProxyVideo remoteServiceVideo = client1.getService("video"); + // Update path: + if (remoteServiceVideo.exist() == true) { + // Send a full path: + installVideoPath(remoteServiceVideo, "testVideo"); + } else { + APPL_ERROR("Can not get service Picture ..."); + } + // List all data: + if (remoteServiceVideo.exist() == true) { + + + } + } + + int32_t iii=0; while (iii < 3) { std::this_thread::sleep_for(std::chrono::milliseconds(500)); diff --git a/test/client/lutin_zeus-test-client.py b/test/client/lutin_zeus-test-client.py index 7aa72e5..89d7e05 100644 --- a/test/client/lutin_zeus-test-client.py +++ b/test/client/lutin_zeus-test-client.py @@ -29,7 +29,8 @@ def configure(target, my_module): my_module.add_depend([ 'zeus', 'zeus-service-user', - 'zeus-service-picture' + 'zeus-service-picture', + 'zeus-service-video' ]) my_module.add_src_file([ 'appl/debug.cpp', diff --git a/tools/architecture.txt b/tools/architecture.txt index c6d584c..671c925 100644 --- a/tools/architecture.txt +++ b/tools/architecture.txt @@ -10,7 +10,7 @@ | | |<-+ | | | | *-----------------------* | +-------------------+ | | |<----------->| service-picture | | | | - +---------->| GATEWAY | *-----------------------* |<===>| USER X data | + +---------->| GATEWAY | *-----------------------* |<===>| USER X data | (ex amazon cloud unlimited) | | | |<------+ | | | | | | | | *-----------------------* | +-------------------+ | | | |<--+ +---->| service-video | | diff --git a/tools/service-picture/appl/main-service-picture.cpp b/tools/service-picture/appl/main-service-picture.cpp index 5a1e90d..64575d0 100644 --- a/tools/service-picture/appl/main-service-picture.cpp +++ b/tools/service-picture/appl/main-service-picture.cpp @@ -83,7 +83,7 @@ namespace appl { return m_listFile.size(); } - std::vector mediaIdGetName(uint32_t _start, uint32_t _stop) override { + std::vector mediaIdGetRange(uint32_t _start, uint32_t _stop) override { std::unique_lock lock(g_mutex); // TODO : Check right ... std::vector out; diff --git a/tools/service-picture/appl/zeus-media.obj.zeus.idl b/tools/service-picture/appl/zeus-media.obj.zeus.idl new file mode 100644 index 0000000..0950944 --- /dev/null +++ b/tools/service-picture/appl/zeus-media.obj.zeus.idl @@ -0,0 +1,50 @@ +#elem-brief: Media interface management +#elem-version: 1.0 +#elem-type:MEDIA +#elem-author:Heero Yui #include #include +#include #include #include @@ -20,311 +21,306 @@ #include #include #include +#include +#include static std::mutex g_mutex; static std::string g_basePath; static std::string g_baseDBName = std::string(SERVICE_NAME) + "-database.json"; -static ejson::Document g_database; -static std::map m_listFile; -static uint64_t m_lastMaxId = 0; +class FileProperty { + public: + uint64_t m_id; //!< use local reference ID to have faster access on the file ... + std::string m_fileName; // Sha 512 + std::string m_name; + std::string m_mineType; + echrono::Time m_creationData; + std::map m_metadata; +}; +static std::vector m_listFile; -static uint64_t createFileID() { +static uint64_t m_lastMaxId = 0; +static bool g_needToStore = false; + +static uint64_t createUniqueID() { m_lastMaxId++; return m_lastMaxId; } namespace appl { - class VideoService : public zeus::service::Video { + class VideoService : public zeus::service::Video { private: + //ememory::SharedPtr& m_client; zeus::ProxyClientProperty m_client; std::string m_userName; public: /* - VideoService(ememory::SharedPtr _client, const std::string& _userName) : + VideoService(ememory::SharedPtr& _client, const std::string& _userName) : m_client(_client), m_userName(_userName) { APPL_WARNING("New VideoService ... for user: "); } */ VideoService(uint16_t _clientId) { - APPL_WARNING("New VideoService ... for user: "); + APPL_VERBOSE("New VideoService ... for user: " << _clientId); } ~VideoService() { - APPL_WARNING("delete VideoService ..."); + APPL_VERBOSE("delete VideoService ..."); } public: - std::vector getAlbums() { - std::unique_lock lock(g_mutex); - std::vector out; - ejson::Array globalGroups = g_database["group-global"].toArray(); - if (globalGroups.exist() == false) { - APPL_DEBUG("'group-global' ==> does not exist ==> No album"); - return out; - } - ejson::Object groups = g_database["groups"].toObject(); - if (groups.exist() == false) { - APPL_DEBUG("'group' ==> does not exist ==> No album"); - return out; - } - APPL_DEBUG("for element in 'group-global'"); - for (auto it: globalGroups) { - std::string tmpString = it.toString().get(); - if (tmpString == "") { - continue; - } - APPL_DEBUG(" find emlement:" << tmpString); - out.push_back(tmpString); - } - return out; - /* - ejson::Object groups = g_database["groups"].toObject(); - if (groups.exist() == false) { - return std::vector(); - } - groups - return getSubAlbums(""); - */ - } - // Get the list of sub album - std::vector getSubAlbums(std::string _parrentAlbum) { - std::unique_lock lock(g_mutex); - std::vector out; - ejson::Object groups = g_database["groups"].toObject(); - if (groups.exist() == false) { - return out; - } - // find parrentAlbum ==> to get sub group - /* - for (size_t iii=0; iii lock(g_mutex); - ejson::Object groups = g_database["groups"].toObject(); - if (groups.exist() == false) { - // TODO : Throw an error ... - return 0; - } - ejson::Object group = groups[_album].toObject(); - if (group.exist() == false) { - // TODO : Throw an error ... - return 0; - } - ejson::Array groupSubs = group["files"].toArray(); - // TODO: Check right - return groupSubs.size(); - } - // Return the list of the album files - std::vector getAlbumListPicture(std::string _album) { - std::unique_lock lock(g_mutex); - std::vector out; - ejson::Object groups = g_database["groups"].toObject(); - if (groups.exist() == false) { - // TODO : Throw an error ... - return out; - } - ejson::Object group = groups[_album].toObject(); - if (group.exist() == false) { - // TODO : Throw an error ... - return out; - } - ejson::Array groupSubs = group["files"].toArray(); - - for (auto it: groupSubs) { - uint64_t id = it.toNumber().getU64(); - /* - auto itImage = m_listFile.find(id); - if (itImage == m_listFile.end()) { - - }*/ - if (id == 0) { - continue; - } - out.push_back(etk::to_string(id)); - } - return out; - } - /* - // Return a File Data (might be a picture .tiff/.png/.jpg) - zeus::FileServer getAlbumPicture(std::string _pictureName) { + uint32_t mediaIdCount() override { std::unique_lock lock(g_mutex); // TODO : Check right ... - uint64_t id = etk::string_to_uint64_t(_pictureName); - APPL_WARNING("try to get file : " << _pictureName << " with id=" << id); - { - auto it = m_listFile.find(id); - if (it != m_listFile.end()) { - return zeus::FileServer(g_basePath + it->second); - } + return m_listFile.size(); + } + + std::vector mediaIdGetName(uint32_t _start, uint32_t _stop) override { + std::unique_lock lock(g_mutex); + // TODO : Check right ... + std::vector out; + for (size_t iii=_start; iii mediaGet(uint32_t _mediaId) override { + std::unique_lock lock(g_mutex); + // TODO : Check right ... + //Check if the file exist: + bool find = false; + FileProperty property; for (auto &it : m_listFile) { - APPL_WARNING("compare: " << it.first << " with " << id << " " << it.second); - if (it.first == id) { - return zeus::FileServer(g_basePath + it.second); + if (it.m_id == _mediaId) { + find = true; + property = it; + break; } } - APPL_ERROR(" ==> Not find ..."); - return zeus::FileServer(); + if (find == false) { + throw std::invalid_argument("Wrong file name ..."); + } + return zeus::File::create(g_basePath + property.m_fileName + "." + zeus::getExtention(property.m_mineType), "", property.m_mineType); } - std::string addFile(zeus::File _dataFile) { + uint32_t mediaAdd(zeus::ProxyFile _dataFile) override { std::unique_lock lock(g_mutex); // TODO : Check right ... - APPL_ERROR(" ==> Receive FILE " << _dataFile.getMineType() << " size=" << _dataFile.getData().size()); - uint64_t id = createFileID(); - std::stringstream val; - val << std::hex << std::setw(16) << std::setfill('0') << id; - std::string filename = val.str(); - filename += "."; - filename += zeus::getExtention(_dataFile.getMineType()); - _dataFile.storeIn(g_basePath + filename); - m_listFile.insert(std::make_pair(id, filename)); - return etk::to_string(id);//zeus::FileServer(); + uint64_t id = createUniqueID(); + + auto futType = _dataFile.getMineType(); + auto futName = _dataFile.getName(); + std::string tmpFileName = g_basePath + "tmpImport_" + etk::to_string(id); + std::string sha512String = zeus::storeInFile(_dataFile, tmpFileName); + futType.wait(); + futName.wait(); + // TODO : Get internal data of the file and remove all the meta-data ==> proper files ... + for (auto &it : m_listFile) { + if (it.m_fileName == sha512String) { + APPL_INFO("File already registered at " << it.m_creationData); + // TODO : Check if data is identical ... + // remove temporary file + etk::FSNodeRemove(tmpFileName); + return it.m_id; + } + } + // move the file at the good position: + APPL_DEBUG("move temporay file in : " << g_basePath << sha512String); + if (etk::FSNodeGetSize(tmpFileName) == 0) { + APPL_ERROR("try to store an empty file"); + throw std::runtime_error("file size == 0"); + } + etk::FSNodeMove(tmpFileName, g_basePath + sha512String + "." + zeus::getExtention(futType.get())); + FileProperty property; + property.m_id = id; + property.m_fileName = sha512String; + property.m_name = futName.get(); + property.m_mineType = futType.get(); + property.m_creationData = echrono::Time::now(); + m_listFile.push_back(property); + g_needToStore = true; + APPL_DEBUG(" filename : " << sha512String); + return id; + } + void mediaRemove(uint32_t _mediaId) override { + std::unique_lock lock(g_mutex); + // TODO : Check right ... + //Check if the file exist: + bool find = false; + FileProperty property; + for (auto &it : m_listFile) { + if (it.m_id == _mediaId) { + find = true; + property = it; + break; + } + } + if (find == false) { + throw std::invalid_argument("Wrong file name ..."); + } + // Real Remove definitly the file + // TODO : Set it in a trash ... For a while ... + if (etk::FSNodeRemove(g_basePath + property.m_fileName + "." + zeus::getExtention(property.m_mineType)) == false) { + throw std::runtime_error("Can not remove file ..."); + } } - - - - */ - /* - // Return a global UTC time - zeus::Time getAlbumPictureTime(std::string _pictureName) { - return m_user->getAlbumPictureTime(_pictureName); - } - // Return a Geolocalization information (latitude, longitude) - zeus::Geo getAlbumPictureGeoLocalization(std::string _pictureName) { - return m_user->getAlbumPictureGeoLocalization(_pictureName); - } - */ - bool removeFile(std::string _file) { + std::vector mediaMetadataGetKeys(uint32_t _mediaId) override { std::unique_lock lock(g_mutex); - // TODO : Check right ... - return false; + std::vector out; + for (auto &it : m_listFile) { + if (it.m_id == _mediaId) { + for (auto &itM : it.m_metadata) { + out.push_back(itM.first); + } + return out; + } + } + throw std::invalid_argument("Wrong KEY ID ..."); + } + std::string mediaMetadataGetKey(uint32_t _mediaId, std::string _key) override { + std::unique_lock lock(g_mutex); + std::vector out; + for (auto &it : m_listFile) { + if (it.m_id == _mediaId) { + auto itM = it.m_metadata.find(_key); + if (itM != it.m_metadata.end()) { + return itM->second; + } + return ""; + } + } + throw std::invalid_argument("Wrong KEY ID ..."); + } + void mediaMetadataSetKey(uint32_t _mediaId, std::string _key, std::string _value) override { + APPL_INFO("[" << _mediaId << "] set key: '" << _key << "' value: '" << _value << "'"); + std::unique_lock lock(g_mutex); + for (auto &it : m_listFile) { + if (it.m_id == _mediaId) { + auto itM = it.m_metadata.find(_key); + if (itM != it.m_metadata.end()) { + itM->second = _value; + } else { + it.m_metadata.insert(std::make_pair(_key, _value)); + } + return; + } + } + throw std::invalid_argument("Wrong KEY ID ..."); + } + std::vector getMediaWhere(std::string _sqlLikeRequest) override { + std::unique_lock lock(g_mutex); + std::vector out; + if (_sqlLikeRequest == "") { + throw std::invalid_argument("empty request"); + } + std::vector listAnd = etk::split(_sqlLikeRequest, "AND"); + APPL_INFO("Find list AND : "); + for (auto &it : listAnd) { + APPL_INFO(" - '" << it << "'"); + } + + return out; } - std::string createAlbum(std::string _name) { + std::vector getMetadataValuesWhere(std::string _keyName, std::string _sqlLikeRequest) override { std::unique_lock lock(g_mutex); - // TODO : Check right ... - return ""; + std::vector out; + + return out; } - bool removeAlbum(std::string _name) { - std::unique_lock lock(g_mutex); - // TODO : Check right ... - return false; - } - bool setAlbumDescription(std::string _name, std::string _desc) { - std::unique_lock lock(g_mutex); - // TODO : Check right ... - return false; - } - std::string getAlbumDescription(std::string _name) { - std::unique_lock lock(g_mutex); - // TODO : Check right ... - return ""; - } - bool addInAlbum(std::string _nameAlbum, std::string _nameElement) { - std::unique_lock lock(g_mutex); - // TODO : Check right ... - return false; - } - bool removeFromAlbum(std::string _nameAlbum, std::string _nameElement) { - std::unique_lock lock(g_mutex); - // TODO : Check right ... - return false; - } - /* - // Return a global UTC time - zeus::Time getAlbumPictureTime(std::string _pictureName) { - std::unique_lock lock(g_mutex); - // TODO : Check right ... - return zeus::Time(); - } - // Return a Geolocalization information (latitude, longitude) - zeus::Geo getAlbumPictureGeoLocalization(std::string _pictureName) { - std::unique_lock lock(g_mutex); - // TODO : Check right ... - return zeus::Geo(); - } - */ + }; } +static void store_db() { + APPL_ERROR("Store database [START]"); + ejson::Document database; + ejson::Array listFilesArray; + database.add("list-files", listFilesArray); + for (auto &it : m_listFile) { + ejson::Object fileElement; + listFilesArray.add(fileElement); + fileElement.add("id", ejson::Number(it.m_id)); + fileElement.add("file-name", ejson::String(it.m_fileName)); + fileElement.add("name", ejson::String(it.m_name)); + fileElement.add("mine-type", ejson::String(it.m_mineType)); + fileElement.add("add-date", ejson::Number(it.m_creationData.count())); + if (it.m_metadata.size() != 0) { + ejson::Object listMetadata; + fileElement.add("meta", listMetadata); + for (auto &itM : it.m_metadata) { + listMetadata.add(itM.first, ejson::String(itM.second)); + } + } + } + bool retGenerate = database.storeSafe(g_basePath + g_baseDBName); + APPL_ERROR("Store database [STOP] : " << (g_basePath + g_baseDBName) << " ret = " << retGenerate); + g_needToStore = false; +} + +static void load_db() { + ejson::Document database; + bool ret = database.load(g_basePath + g_baseDBName); + if (ret == false) { + APPL_WARNING(" ==> LOAD error"); + } + ejson::Array listFilesArray = database["list-files"].toArray(); + for (const auto itArray: listFilesArray) { + ejson::Object fileElement = itArray.toObject(); + FileProperty property; + property.m_id = fileElement["id"].toNumber().getU64(); + APPL_INFO("get ID : " << property.m_id); + property.m_fileName = fileElement["file-name"].toString().get(); + property.m_name = fileElement["name"].toString().get(); + property.m_mineType = fileElement["mine-type"].toString().get(); + property.m_creationData = echrono::Time(fileElement["add-date"].toNumber().getU64()*1000); + if (m_lastMaxId < property.m_id) { + m_lastMaxId = property.m_id+1; + } + ejson::Object tmpObj = fileElement["meta"].toObject(); + if (tmpObj.exist() == true) { + for (auto itValue = tmpObj.begin(); + itValue != tmpObj.end(); + ++itValue) { + property.m_metadata.insert(std::make_pair(itValue.getKey(), (*itValue).toString().get())); + } + } + if (property.m_fileName == "") { + APPL_ERROR("Can not access on the file : ... No name "); + } else { + m_listFile.push_back(property); + } + } + g_needToStore = false; +} + ETK_EXPORT_API bool SERVICE_IO_init(int _argc, const char *_argv[], std::string _basePath) { g_basePath = _basePath; std::unique_lock lock(g_mutex); APPL_WARNING("Load USER: " << g_basePath); - bool ret = g_database.load(g_basePath + g_baseDBName); - if (ret == false) { - APPL_WARNING(" ==> LOAD error"); - } - // Load all files (image and video ...) - etk::FSNode node(g_basePath); - std::vector tmpList = node.folderGetSubList(false, false, true, false); - APPL_WARNING("Find " << tmpList.size() << " files"); - for (auto &it : tmpList) { - if (it == nullptr) { - continue; - } - if ( etk::end_with(it->getNameFile(), ".svg", false) == true - || etk::end_with(it->getNameFile(), ".bmp", false) == true - || etk::end_with(it->getNameFile(), ".png", false) == true - || etk::end_with(it->getNameFile(), ".jpg", false) == true - || etk::end_with(it->getNameFile(), ".tga", false) == true - || etk::end_with(it->getNameFile(), ".mp4", false) == true - || etk::end_with(it->getNameFile(), ".avi", false) == true - || etk::end_with(it->getNameFile(), ".mov", false) == true - || etk::end_with(it->getNameFile(), ".mkv", false) == true) { - // TODO : Do it better (proto ..) - std::string idString = it->getNameFile(); - idString.resize(idString.size()-4); - uint64_t id = 0; - std::stringstream ss; - ss << std::hex << idString; - ss >> id; - if (id <= 1024) { - APPL_WARNING(" ==> REJECTED file " << it->getNameFile() << " with ID = " << id); - } else { - m_listFile.insert(std::make_pair(id, it->getNameFile())); - m_lastMaxId = std::max(m_lastMaxId,id); - APPL_WARNING(" ==> load file " << it->getNameFile() << " with ID = " << id); - } - } else { - APPL_WARNING(" ==> REJECT file " << it->getNameFile()); - } - } + load_db(); APPL_WARNING("new USER: [STOP]"); return true; } ETK_EXPORT_API bool SERVICE_IO_uninit() { std::unique_lock lock(g_mutex); - APPL_DEBUG("Store User Info:"); - bool ret = g_database.storeSafe(g_basePath + g_baseDBName); - if (ret == false) { - APPL_WARNING(" ==> Store error"); - return false; - } + store_db(); APPL_WARNING("delete USER [STOP]"); return true; } +ETK_EXPORT_API void SERVICE_IO_peridic_call() { + if (g_needToStore == false) { + return; + } + // try lock mutex: + if (g_mutex.try_lock() == false) { + return; + } + store_db(); + g_mutex.unlock(); +} + + ZEUS_SERVICE_VIDEO_DECLARE(appl::VideoService); diff --git a/tools/service-video/appl/zeus-service-video.srv.zeus.idl b/tools/service-video/appl/zeus-service-video.srv.zeus.idl index d2c492f..5951421 100644 --- a/tools/service-video/appl/zeus-service-video.srv.zeus.idl +++ b/tools/service-video/appl/zeus-service-video.srv.zeus.idl @@ -1,20 +1,85 @@ -#elem-brief: video interface management +#elem-brief: picture interface management #elem-version: 1.0 -#elem-type:VIDEO -#elem-author:Heero Yui +#elem-type:PICTURE +#elem-author:Heero Yui +#include + +void zeus::FutureGroup::add(const zeus::FutureBase& _fut) { + m_listFuture.push_back(_fut); +} + +void zeus::FutureGroup::wait() const { + waitFor(); +} + +void zeus::FutureGroup::waitFor(echrono::Duration _delta) const { + waitUntil(echrono::Steady::now() + _delta); +} + +void zeus::FutureGroup::waitUntil(echrono::Steady _endTime) const { + bool allIsFinished = false; + while ( echrono::Steady::now() < _endTime + && allIsFinished == false) { + allIsFinished = true; + for (auto &it : m_listFuture) { + if (it.isFinished() == false) { + allIsFinished = false; + } + } + std::this_thread::sleep_for(echrono::milliseconds(10)); + } + if (allIsFinished == false) { + ZEUS_WARNING("Group Wait timeout ..."); + } +} diff --git a/zeus/FutureGroup.hpp b/zeus/FutureGroup.hpp new file mode 100644 index 0000000..a6182d5 --- /dev/null +++ b/zeus/FutureGroup.hpp @@ -0,0 +1,39 @@ +/** @file + * @author Edouard DUPIN + * @copyright 2014, Edouard DUPIN, all right reserved + * @license APACHE v2.0 (see license file) + */ +#pragma once + +#include +#include + +namespace zeus { + /** + * @brief Class that permit to add all waiting feture inside this group and wait only one time + */ + class FutureGroup { + private: + std::vector m_listFuture; + public: + void add(const zeus::FutureBase& _fut); + /** + * @brief Wait the Future receive data + * @return reference on the current futur + */ + void wait() const; + /** + * @brief Wait the Future receive data + * @param[in] _delta delay to wait the data arrive + * @return reference on the current futur + */ + void waitFor(echrono::Duration _delta = echrono::seconds(30)) const; + /** + * @brief Wait the Future receive data + * @param[in] _endTime tiem to wait the data + * @return reference on the current futur + */ + void waitUntil(echrono::Steady _endTime) const; + }; +} +