[DEV] start think at video interface

This commit is contained in:
Edouard DUPIN 2016-12-28 15:34:05 +01:00
parent 7f1883dbea
commit ac206580d3
11 changed files with 627 additions and 288 deletions

View File

@ -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

View File

@ -17,9 +17,11 @@
#include <etk/stdTools.hpp>
#include <zeus/service/ProxyUser.hpp>
#include <zeus/service/ProxyPicture.hpp>
#include <zeus/service/ProxyVideo.hpp>
#include <zeus/ProxyFile.hpp>
#include <zeus/ObjectRemote.hpp>
#include <echrono/Steady.hpp>
#include <zeus/FutureGroup.hpp>
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<std::string,std::string> _basicKey = std::map<std::string,std::string>()) {
etk::FSNode node(_path);
APPL_INFO("Parse : '" << _path << "'");
std::vector<std::string> listSubPath = node.folderGetSub(true, false, "*");
for (auto &itPath : listSubPath) {
std::map<std::string,std::string> 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<std::string,std::string>("type", "film"));
basicKeyTmp.insert(std::pair<std::string,std::string>("production-methode", "picture"));
} else if (lastPathName == "films-annimation") {
basicKeyTmp.insert(std::pair<std::string,std::string>("type", "film"));
basicKeyTmp.insert(std::pair<std::string,std::string>("production-methode", "draw"));
} else if (lastPathName == "tv-show") {
basicKeyTmp.insert(std::pair<std::string,std::string>("type", "tv-show"));
basicKeyTmp.insert(std::pair<std::string,std::string>("production-methode", "picture"));
} else if (lastPathName == "anim") {
basicKeyTmp.insert(std::pair<std::string,std::string>("type", "tv-show"));
basicKeyTmp.insert(std::pair<std::string,std::string>("production-methode", "draw"));
} else if (lastPathName == "courses") { // short films
basicKeyTmp.insert(std::pair<std::string,std::string>("type", "courses"));
basicKeyTmp.insert(std::pair<std::string,std::string>("production-methode", "picture")); // TODO : Check "draw"
} else if (lastPathName == "theater") {
basicKeyTmp.insert(std::pair<std::string,std::string>("type", "theater"));
basicKeyTmp.insert(std::pair<std::string,std::string>("production-methode", "picture"));
} else if (lastPathName == "one-man-show") {
basicKeyTmp.insert(std::pair<std::string,std::string>("type", "one-man show"));
basicKeyTmp.insert(std::pair<std::string,std::string>("production-methode", "picture"));
}
} else {
APPL_INFO("find '" << lastPathName << "' " << basicKeyTmp.size());
if (lastPathName == "saison_01") {
basicKeyTmp.insert(std::pair<std::string,std::string>("saison", "1"));
} else if (lastPathName == "saison_02") {
basicKeyTmp.insert(std::pair<std::string,std::string>("saison", "2"));
} else if (lastPathName == "saison_03") {
basicKeyTmp.insert(std::pair<std::string,std::string>("saison", "3"));
} else if (lastPathName == "saison_04") {
basicKeyTmp.insert(std::pair<std::string,std::string>("saison", "4"));
} else if (lastPathName == "saison_05") {
basicKeyTmp.insert(std::pair<std::string,std::string>("saison", "5"));
} else if (lastPathName == "saison_06") {
basicKeyTmp.insert(std::pair<std::string,std::string>("saison", "6"));
} else if (lastPathName == "saison_07") {
basicKeyTmp.insert(std::pair<std::string,std::string>("saison", "7"));
} else if (lastPathName == "saison_08") {
basicKeyTmp.insert(std::pair<std::string,std::string>("saison", "8"));
} else if (lastPathName == "saison_09") {
basicKeyTmp.insert(std::pair<std::string,std::string>("saison", "9"));
} else if (lastPathName == "saison_10") {
basicKeyTmp.insert(std::pair<std::string,std::string>("saison", "10"));
} else if (lastPathName == "saison_11") {
basicKeyTmp.insert(std::pair<std::string,std::string>("saison", "11"));
} else if (lastPathName == "saison_12") {
basicKeyTmp.insert(std::pair<std::string,std::string>("saison", "12"));
} else if (lastPathName == "saison_13") {
basicKeyTmp.insert(std::pair<std::string,std::string>("saison", "13"));
} else if (lastPathName == "saison_14") {
basicKeyTmp.insert(std::pair<std::string,std::string>("saison", "14"));
} else if (lastPathName == "saison_15") {
basicKeyTmp.insert(std::pair<std::string,std::string>("saison", "15"));
} else if (lastPathName == "saison_16") {
basicKeyTmp.insert(std::pair<std::string,std::string>("saison", "16"));
} else if (lastPathName == "saison_17") {
basicKeyTmp.insert(std::pair<std::string,std::string>("saison", "17"));
} else if (lastPathName == "saison_18") {
basicKeyTmp.insert(std::pair<std::string,std::string>("saison", "18"));
} else if (lastPathName == "saison_19") {
basicKeyTmp.insert(std::pair<std::string,std::string>("saison", "19"));
} else if (lastPathName == "saison_20") {
basicKeyTmp.insert(std::pair<std::string,std::string>("saison", "20"));
} else {
basicKeyTmp.insert(std::pair<std::string,std::string>("series-name", lastPathName));
}
}
installVideoPath(_srv, itPath, basicKeyTmp);
}
// Add files :
std::vector<std::string> listSubFile = node.folderGetSub(false, true, "*");
for (auto &itFile : listSubFile) {
std::map<std::string,std::string> 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<std::string> 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<std::string,std::string>("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<std::vector<uint32_t>> 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));

View File

@ -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',

View File

@ -10,7 +10,7 @@
| | |<-+ |
| | | *-----------------------* | +-------------------+
| | |<----------->| service-picture | | | |
+---------->| GATEWAY | *-----------------------* |<===>| USER X data |
+---------->| GATEWAY | *-----------------------* |<===>| USER X data | (ex amazon cloud unlimited)
| | | |<------+ | | |
| | | | | *-----------------------* | +-------------------+
| | | |<--+ +---->| service-video | |

View File

@ -83,7 +83,7 @@ namespace appl {
return m_listFile.size();
}
std::vector<uint32_t> mediaIdGetName(uint32_t _start, uint32_t _stop) override {
std::vector<uint32_t> mediaIdGetRange(uint32_t _start, uint32_t _stop) override {
std::unique_lock<std::mutex> lock(g_mutex);
// TODO : Check right ...
std::vector<uint32_t> out;

View File

@ -0,0 +1,50 @@
#elem-brief: Media interface management
#elem-version: 1.0
#elem-type:MEDIA
#elem-author:Heero Yui<yui.heero@gmail.com
import zeus-File
// ----------------- meta-data Access -----------------------
/*
#brief:Get all meta-data of a media
#return:a json description of the metadata
json mediaMetadataGet()
*/
#brief:Get all meta-data keys of a media
#return:List of all availlable keys
vector:string metadataGetKeys()
#brief:Get a meta-data value of a key
#param:key:Key of the meta-data
#return:data in the key
string metadataGetKey(string)
#brief:Set a meta-data value of a key
#param:key:Key of the meta-data
#param:value:data in the key
void metadataSetKey(string, string)
/*
#brief:Set all meta-data of a media
#param:description: a json description of the metadata
void mediaMetadataSet(json)
*/
// ----------------- media Access -----------------------
#brief:Get a media
#return:A file reference on the media (transmission is async)
obj:zeus-File getFile()
/*
#brief:Get a media in STREAM mode (usefull for video)
#return:A stream reference on the media (transmission is async)
obj::zeus-Stream getStream()
*/
#brief:Remove a media in the service (no trash)
void remove()

View File

@ -10,28 +10,12 @@ import zeus-File
#return: Number of media
uint32 mediaIdCount()
#brief:Get list of name of the media in a specific range (<1024)
#brief:Get range list of media ids in a specific range (<1024)
#param:start:First Id of the media stream requested (range [0..+inf[)
#param:stop:Last Id of the media stream requested (excluded) (range [0..+inf[)
#return:List of the media Ids
vector:uint32 mediaIdGetName(uint32,uint32)
vector:uint32 mediaIdGetRange(uint32,uint32)
/*
// ----------------- Get media with their ID in a range of time -----------------------
#brief:Get the number of media availlable in a range of time
#param:timeStart:First time that the element is requested
#param:timeStop:Last time the count is requested
#return: Number of media in this range of time
uint32 mediaTimeCount(time, time)
#brief:Get list of name of the media in a specific range (<1024)
#param:timeStart:First time that the element is requested
#param:timeStop:Last time the count is requested
#param:start:First Id of the media stream requested (range [0..+inf[)
#param:stop:Last Id of the media stream requested (excluded) (range [0..+inf[)
#return:List of the media names
vector:string mediaTimeGetName(time, time, uint32,uint32)
*/
// ----------------- media Access -----------------------
#brief:Get a media
#param:mediaId:Id of the media

View File

@ -9,6 +9,7 @@
#include <zeus/File.hpp>
#include <etk/etk.hpp>
#include <zeus/zeus.hpp>
#include <echrono/Time.hpp>
#include <mutex>
#include <ejson/ejson.hpp>
@ -20,15 +21,27 @@
#include <zeus/service/Video.hpp>
#include <zeus/service/registerVideo.hpp>
#include <zeus/ProxyClientProperty.hpp>
#include <zeus/File.hpp>
#include <zeus/ProxyFile.hpp>
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<uint64_t,std::string> 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<std::string, std::string> m_metadata;
};
static std::vector<FileProperty> 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;
}
@ -36,295 +49,278 @@ static uint64_t createFileID() {
namespace appl {
class VideoService : public zeus::service::Video {
private:
//ememory::SharedPtr<zeus::ClientProperty>& m_client;
zeus::ProxyClientProperty m_client;
std::string m_userName;
public:
/*
VideoService(ememory::SharedPtr<zeus::ClientProperty> _client, const std::string& _userName) :
VideoService(ememory::SharedPtr<zeus::ClientProperty>& _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<std::string> getAlbums() {
std::unique_lock<std::mutex> lock(g_mutex);
std::vector<std::string> 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<std::string>();
}
groups
return getSubAlbums("");
*/
}
// Get the list of sub album
std::vector<std::string> getSubAlbums(std::string _parrentAlbum) {
std::unique_lock<std::mutex> lock(g_mutex);
std::vector<std::string> 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<groups.size(); ++iii) {
//ejson::Object group = groups[iii].toObject()["sub"];
if (groups.getKey(iii) != _parrentAlbum) {
continue;
}
}
*/
ejson::Object group = groups[_parrentAlbum].toObject();
if (group.exist() == false) {
return out;
}
ejson::Array groupSubs = group["sub"].toArray();
for (auto it: groupSubs) {
std::string tmpString = it.toString().get();
if (tmpString == "") {
continue;
}
out.push_back(tmpString);
}
// TODO: Check right
return out;
}
uint32_t getAlbumCount(std::string _album) {
std::unique_lock<std::mutex> 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<std::string> getAlbumListPicture(std::string _album) {
std::unique_lock<std::mutex> lock(g_mutex);
std::vector<std::string> 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<std::mutex> 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<uint32_t> mediaIdGetName(uint32_t _start, uint32_t _stop) override {
std::unique_lock<std::mutex> lock(g_mutex);
// TODO : Check right ...
std::vector<uint32_t> out;
for (size_t iii=_start; iii<m_listFile.size() && iii<_stop; ++iii) {
out.push_back(m_listFile[iii].m_id);
}
return out;
}
// Return a File Data (might be a video .tiff/.png/.jpg)
ememory::SharedPtr<zeus::File> mediaGet(uint32_t _mediaId) override {
std::unique_lock<std::mutex> 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 ...");
}
std::string addFile(zeus::File _dataFile) {
return zeus::File::create(g_basePath + property.m_fileName + "." + zeus::getExtention(property.m_mineType), "", property.m_mineType);
}
uint32_t mediaAdd(zeus::ProxyFile _dataFile) override {
std::unique_lock<std::mutex> 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;
}
*/
/*
// 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);
// 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");
}
*/
bool removeFile(std::string _file) {
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<std::mutex> lock(g_mutex);
// TODO : Check right ...
return false;
//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 ...");
}
}
std::string createAlbum(std::string _name) {
std::vector<std::string> mediaMetadataGetKeys(uint32_t _mediaId) override {
std::unique_lock<std::mutex> lock(g_mutex);
// TODO : Check right ...
std::vector<std::string> 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<std::mutex> lock(g_mutex);
std::vector<std::string> 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 "";
}
bool removeAlbum(std::string _name) {
std::unique_lock<std::mutex> lock(g_mutex);
// TODO : Check right ...
return false;
}
bool setAlbumDescription(std::string _name, std::string _desc) {
std::unique_lock<std::mutex> lock(g_mutex);
// TODO : Check right ...
return false;
throw std::invalid_argument("Wrong KEY ID ...");
}
std::string getAlbumDescription(std::string _name) {
void mediaMetadataSetKey(uint32_t _mediaId, std::string _key, std::string _value) override {
APPL_INFO("[" << _mediaId << "] set key: '" << _key << "' value: '" << _value << "'");
std::unique_lock<std::mutex> lock(g_mutex);
// TODO : Check right ...
return "";
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));
}
bool addInAlbum(std::string _nameAlbum, std::string _nameElement) {
return;
}
}
throw std::invalid_argument("Wrong KEY ID ...");
}
std::vector<uint32_t> getMediaWhere(std::string _sqlLikeRequest) override {
std::unique_lock<std::mutex> lock(g_mutex);
// TODO : Check right ...
return false;
std::vector<uint32_t> out;
if (_sqlLikeRequest == "") {
throw std::invalid_argument("empty request");
}
bool removeFromAlbum(std::string _nameAlbum, std::string _nameElement) {
std::vector<std::string> listAnd = etk::split(_sqlLikeRequest, "AND");
APPL_INFO("Find list AND : ");
for (auto &it : listAnd) {
APPL_INFO(" - '" << it << "'");
}
return out;
}
std::vector<std::string> getMetadataValuesWhere(std::string _keyName, std::string _sqlLikeRequest) override {
std::unique_lock<std::mutex> lock(g_mutex);
// TODO : Check right ...
return false;
std::vector<std::string> out;
return out;
}
/*
// Return a global UTC time
zeus::Time getAlbumPictureTime(std::string _pictureName) {
std::unique_lock<std::mutex> lock(g_mutex);
// TODO : Check right ...
return zeus::Time();
}
// Return a Geolocalization information (latitude, longitude)
zeus::Geo getAlbumPictureGeoLocalization(std::string _pictureName) {
std::unique_lock<std::mutex> 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<std::mutex> 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<etk::FSNode*> 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<std::mutex> 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);

View File

@ -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<yui.heero@gmail.com>
#elem-type:PICTURE
#elem-author:Heero Yui<yui.heero@gmail.com
vector:string getAlbums()
vector:string getSubAlbums(string)
uint32 getAlbumCount(string)
vector:string getAlbumListPicture(string)
//zeus::FileServer getAlbumPicture(string)
//string addFile(zeus::File)
bool removeFile(string)
import zeus-File
// ----------------- Get media with their ID -----------------------
#brief:Get the number of media availlable (a media is a picture or a video)
#return: Number of media
uint32 mediaIdCount()
#brief:Get list of name of the media in a specific range (<1024)
#param:start:First Id of the media stream requested (range [0..+inf[)
#param:stop:Last Id of the media stream requested (excluded) (range [0..+inf[)
#return:List of the media Ids
vector:uint32 mediaIdGetName(uint32,uint32)
// ----------------- media Access -----------------------
#brief:Get a media
#param:mediaId:Id of the media
#return:A file reference on the media (transmission is async)
obj:zeus-File mediaGet(uint32)
/*
string createAlbum(string)
bool removeAlbum(string)
bool setAlbumDescription(string, string)
string getAlbumDescription(string)
bool addInAlbum(string, string)
bool removeFromAlbum(string, string)
#brief:Get a media in STREAM mode (usefull for video)
#param:mediaId:Id of the media
#return:A stream reference on the media (transmission is async)
obj::zeus-Stream mediaStream(uint32)
*/
#brief:Add a new media in the service
#param:data:A file reference on the media (transmission is async)
#return:Local personal ID of the media
uint32 mediaAdd(obj:zeus-File)
#brief:Remove a media in the service (no trash)
#param:mediaId:Id of the media
void mediaRemove(uint32)
// ----------------- meta-data Access -----------------------
/*
#brief:Get all meta-data of a media
#param:mediaName:Name of the media
#return:a json description of the metadata
json mediaMetadataGet(string)
*/
#brief:Get all meta-data keys of a media
#param:mediaId:Id of the media
#return:List of all availlable keys
vector:string mediaMetadataGetKeys(uint32)
#brief:Get a meta-data value of a key
#param:mediaId:Id of the media
#param:key:Key of the meta-data
#return:data in the key
string mediaMetadataGetKey(uint32, string)
#brief:Set a meta-data value of a key
#param:mediaId:Id of the media
#param:key:Key of the meta-data
#param:value:data in the key
void mediaMetadataSetKey(uint32, string, string)
/*
#brief:Set all meta-data of a media
#param:name:Name of the media
#param:description: a json description of the metadata
void mediaMetadataSet(string, json)
*/
/*
The SQL-like is now: ['AND','='] only...
'serie-name' = 'stargate'
AND 'saison' = '2'
*/
#brief:Get a meta-data research elements with a SQL-like request
#param:sqlLikeRequest:A string containing the request on the data
#return:All The requested Data filter by the value
vector:uint32 getMediaWhere(string)
#brief:Get a list of possibilities of a meta-data
#param:keyName:the key metadata whe we want to have list of possibilities
#param:sqlLikeRequest:A string containing the request on the data
#return:All The possible values of a key
vector:string getMetadataValuesWhere(string, string)

37
zeus/FutureGroup.cpp Normal file
View File

@ -0,0 +1,37 @@
/** @file
* @author Edouard DUPIN
* @copyright 2014, Edouard DUPIN, all right reserved
* @license APACHE v2.0 (see license file)
*/
#include <zeus/FutureGroup.hpp>
#include <zeus/debug.hpp>
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 ...");
}
}

39
zeus/FutureGroup.hpp Normal file
View File

@ -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 <zeus/FutureBase.hpp>
#include <vector>
namespace zeus {
/**
* @brief Class that permit to add all waiting feture inside this group and wait only one time
*/
class FutureGroup {
private:
std::vector<zeus::FutureBase> 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;
};
}