[Gallery] Implemented MediaItem::saveToDevice() method 34/128634/4
authorIgor Nazarov <i.nazarov@samsung.com>
Wed, 10 May 2017 17:02:29 +0000 (20:02 +0300)
committerIgor Nazarov <i.nazarov@samsung.com>
Mon, 15 May 2017 14:07:07 +0000 (17:07 +0300)
- Added implementation of MediaItem::saveToDevice() method;
- getProperty() helper function changed to more universal
  util::get[Nz]() using variadic templates;
- Implemented file path utility functions.

Change-Id: I05d83e0f2afd18c1594a15cd75f5107ecbf4e5c8

inc/model/MediaItem.h
src/helpers.h
src/helpers.hpp
src/model/MediaItem.cpp
src/model/helpers.cpp
src/model/helpers.h
src/presenters/Instance.cpp

index 2bcf923cbbbcb6d22547cb7595045c3fe61f50d7..d72f8a4d100671ea95bc630c69ab550686b73e5f 100644 (file)
@@ -38,9 +38,10 @@ namespace gallery {
                enum {
                        FLAG_THUMBNAIL = 1,
                        FLAG_REMOVE = 2,
+                       FLAG_SAVE = 4,
 
                        FLAGS_FROM_MEDIA_DB = (FLAG_THUMBNAIL | FLAG_REMOVE),
-                       FLAGS_SIMPLE_FILE = 0
+                       FLAGS_SIMPLE_FILE = (FLAG_SAVE)
                };
 
        public:
@@ -60,6 +61,7 @@ namespace gallery {
                void cancelThumbnailPathGet() const;
 
                ucl::Result removeFile();
+               ucl::Result saveToDevice();
 
        protected:
                friend class ucl::RefCountObj<MediaItem>;
index d5f99973e97074707fc99fbd216452191fd05cd8..8cd1b3abaa4ea3407d4f58470ff79dca7e04b153 100644 (file)
 #ifndef __GALLERY_HELPERS_H__
 #define __GALLERY_HELPERS_H__
 
-#include <string>
+#include "types.h"
 
-namespace gallery {
+namespace gallery { namespace util {
 
-       template <class T>
-       bool getProperty(T obj, int (*get)(T obj, char **value),
-                       std::string &result, bool optional = false);
+       template <class GETTER, class V, class ...ARGS>
+       ucl::Result get(GETTER &&getter, V &result, ARGS &&...args);
 
-       template <class T, class V>
-       bool getProperty(T obj, int (*get)(T obj, V *value),
-                       V &result, bool mayBeZero = false);
-}
+       template <class GETTER, class V, class ...ARGS>
+       ucl::Result getNz(GETTER &&getter, V &result, ARGS &&...args);
+}}
 
 #include "helpers.hpp"
 
index b617f9af1b8ec04caf6df7a6ffcb27119ffc6969..6acb919096f9b588acd5802260040299b289505b 100644 (file)
 
 #include "ucl/util/logging.h"
 
-namespace gallery {
+namespace gallery { namespace util { namespace himpl {
 
-       template <class T>
-       inline bool getProperty(T obj,
-                       int (*get)(T obj, char **value),
-                       std::string &result, bool optional)
+       template <class GETTER, class ...ARGS>
+       inline ucl::Result get(GETTER &&getter, bool optional,
+                       std::string &result, ARGS &&...args)
        {
                char *value = nullptr;
-               const int ret = get(obj, &value);
+               const int ret = getter(std::forward<ARGS>(args)..., &value);
                if ((ret != 0) || (!optional && !value)) {
                        UCL_ELOG("get() failed: %d", ret);
-                       return false;
+                       return ucl::RES_FAIL;
                }
 
                if (value) {
@@ -37,18 +36,39 @@ namespace gallery {
                        result.clear();
                }
 
-               return true;
+               return ucl::RES_OK;
        }
 
-       template <class T, class V>
-       inline bool getProperty(T obj, int (*get)(T obj, V *value),
-                       V &result, bool mayBeZero)
+       template <class GETTER, class V, class ...ARGS>
+       inline ucl::Result get(GETTER &&getter, bool optional,
+                       V &result, ARGS &&...args)
        {
-               const int ret = get(obj, &result);
-               if ((ret != 0) || (!mayBeZero && !result)) {
+               V value = {};
+               const int ret = getter(std::forward<ARGS>(args)..., &value);
+               if ((ret != 0) || (!optional && !value)) {
                        UCL_ELOG("get() failed: %d", ret);
-                       return false;
+                       return ucl::RES_FAIL;
                }
-               return true;
+
+               result = value;
+
+               return ucl::RES_OK;
+       }
+}}}
+
+namespace gallery { namespace util {
+
+       template <class GETTER, class V, class ...ARGS>
+       inline ucl::Result get(GETTER &&getter, V &result, ARGS &&...args)
+       {
+               return himpl::get(std::forward<GETTER>(getter), true,
+                               result, std::forward<ARGS>(args)...);
+       }
+
+       template <class GETTER, class V, class ...ARGS>
+       inline ucl::Result getNz(GETTER &&getter, V &result, ARGS &&...args)
+       {
+               return himpl::get(std::forward<GETTER>(getter), false,
+                               result, std::forward<ARGS>(args)...);
        }
-}
+}}
index ae888a549a1dd3bb5bfb0c91238bf957ab16470c..2586354da063a465fdf846b57c125f6b4e203fc2 100644 (file)
@@ -17,6 +17,7 @@
 #include "model/MediaItem.h"
 
 #include <Ecore_File.h>
+#include <storage.h>
 
 #include "BaseJob.h"
 
@@ -143,13 +144,11 @@ namespace gallery {
                        }
                }
 
-               if (!getProperty(media, media_info_get_media_id, m_mediaId)) {
-                       LOG_RETURN(RES_FAIL, "getProperty(media_id) failed!");
-               }
+               FAIL_RETURN(util::getNz(media_info_get_media_id, m_mediaId, media),
+                       "media_info_get_media_id() failed!");
 
-               if (!getProperty(media, media_info_get_file_path, m_filePath)) {
-                       LOG_RETURN(RES_FAIL, "getProperty(file_path) failed!");
-               }
+               FAIL_RETURN(util::getNz(media_info_get_file_path, m_filePath, media),
+                       "media_info_get_file_path() failed!");
 
                m_isValid = true;
 
@@ -158,10 +157,8 @@ namespace gallery {
 
        Result MediaItem::initThumbPath(const media_info_h media) const
        {
-               if (!getProperty(media, media_info_get_thumbnail_path,
-                               m_thumbPath, true)) {
-                       LOG_RETURN(RES_FAIL, "getProperty(thumbnail_path) failed!");
-               }
+               FAIL_RETURN(util::get(media_info_get_thumbnail_path, m_thumbPath,
+                       media), "media_info_get_thumbnail_path() failed!");
                return RES_OK;
        }
 
@@ -211,7 +208,7 @@ namespace gallery {
        Result MediaItem::removeFile()
        {
                if (!(m_flags & FLAG_REMOVE)) {
-                       LOG_RETURN(RES_NOT_SUPPORTED, "Operation not suported!");
+                       LOG_RETURN(RES_NOT_SUPPORTED, "Operation not supported!");
                }
                if (!ecore_file_can_write(m_filePath.c_str())) {
                        LOG_RETURN(RES_FAIL, "File can't be removed!");
@@ -230,7 +227,7 @@ namespace gallery {
                }
 
                if (!ecore_file_remove(m_filePath.c_str())) {
-                       FLOG("ecore_file_remove() failed! Attemting to rescan....");
+                       FLOG("ecore_file_remove() failed! Attempting to rescan....");
                        MutexLock lock(getMediaMutex());
                        const int ret = media_content_scan_file(m_filePath.c_str());
                        if (ret != 0) {
@@ -242,10 +239,48 @@ namespace gallery {
                return RES_OK;
        }
 
+       Result MediaItem::saveToDevice()
+       {
+               if (!(m_flags & FLAG_SAVE)) {
+                       LOG_RETURN(RES_NOT_SUPPORTED, "Operation not supported!");
+               }
+
+               int storageId = 0;
+               FAIL_RETURN(getInternalStorageId(storageId),
+                               "getInternalStorageId() failed!");
+
+               std::string imagesDir;
+               FAIL_RETURN(util::getNz(storage_get_directory, imagesDir,
+                               storageId, STORAGE_DIRECTORY_IMAGES),
+                               "storage_get_directory() failed!");
+
+               const std::string savePath = util::makeUniqueFilePath(
+                               m_filePath, imagesDir);
+
+               if (!ecore_file_cp(m_filePath.c_str(), savePath.c_str())) {
+                       LOG_RETURN(RES_FAIL, "ecore_file_cp() failed!");
+               }
+
+               {
+                       MutexLock lock(getMediaMutex());
+                       const int ret = media_content_scan_file(savePath.c_str());
+                       if (ret == 0) {
+                               return RES_OK;
+                       }
+                       ELOG("media_content_scan_file() failed: %d", ret);
+               }
+
+               if (!ecore_file_remove(savePath.c_str())) {
+                       WLOG("ecore_file_remove() failed!");
+               }
+
+               return RES_FAIL;
+       }
+
        Result MediaItem::getThumbnailPath(ThumbnailPathGetCb cb) const
        {
                if (!(m_flags & FLAG_THUMBNAIL)) {
-                       LOG_RETURN(RES_NOT_SUPPORTED, "Operation not suported!");
+                       LOG_RETURN(RES_NOT_SUPPORTED, "Operation not supported!");
                }
                if (!cb) {
                        return RES_INVALID_ARGUMENTS;
@@ -261,7 +296,7 @@ namespace gallery {
                        return RES_FALSE;
                }
 
-               auto cbProxy = util::makeUnique(new ThumbCbProxy{this, cb});
+               auto cbProxy = ucl::util::makeUnique(new ThumbCbProxy{this, cb});
 
                {
                        MutexLock lock(getMediaMutex());
index 4facb8cdcdbc6fb34a46c33ccbff7601707afd9a..4057ff5fbedc06cf8f0e8705c167439bedf3e9c6 100644 (file)
 
 #include "helpers.h"
 
+#include <Ecore_File.h>
+#include <storage.h>
+
 #include "common.h"
 
+namespace gallery { namespace { namespace impl {
+
+       constexpr auto UNIQUE_PATH_RESERVE = 10;
+}}}
+
 namespace gallery {
 
        using namespace ucl;
@@ -27,4 +35,123 @@ namespace gallery {
                static Mutex mutex{true};
                return mutex;
        }
+
+       Result getInternalStorageId(int &result)
+       {
+               struct StorageIdRec {
+                       int id;
+                       bool valid;
+               } storageIdRec {0, false};
+
+               const int ret = storage_foreach_device_supported(
+                       [](int storageId, storage_type_e type,
+                                       storage_state_e state, const char *path, void *userData)
+                       {
+                               if ((type != STORAGE_TYPE_INTERNAL) ||
+                                               (state != STORAGE_STATE_MOUNTED)) {
+                                       return true;
+                               }
+                               auto &storageIdRec = *static_cast<StorageIdRec *>(userData);
+                               storageIdRec.id = storageId;
+                               storageIdRec.valid = true;
+                               return false;
+                       },
+                       &storageIdRec);
+               if (ret != 0) {
+                       LOG_RETURN(RES_FAIL,
+                                       "storage_foreach_device_supported() failed: %d", ret);
+               }
+
+               if (!storageIdRec.valid) {
+                       LOG_RETURN(RES_FAIL, "Writable internal storage not found!");
+               }
+
+               result = storageIdRec.id;
+
+               return RES_OK;
+       }
 }
+
+namespace gallery { namespace util {
+
+       std::string extractFileName(const std::string &path)
+       {
+               const auto bsPos = path.rfind('/');
+               if (bsPos == (path.size() - 1)) {
+                       return {};
+               }
+               return path.substr(bsPos + 1);
+       }
+
+       std::string extractExtension(const std::string &name)
+       {
+               const auto dotPos = name.rfind('.');
+               if ((dotPos == std::string::npos) ||
+                               (dotPos == 0) || (dotPos == (name.size() - 1))) {
+                       return {};
+               }
+               return name.substr(dotPos + 1);
+       }
+
+       void splitFilePath(const std::string &path, std::string &directory,
+                       std::string &baseName, std::string &extension)
+       {
+               splitFileName(path, baseName, extension);
+               if (isNotEmpty(baseName)) {
+                       directory = path.substr(0, (path.size() - baseName.size() -
+                                       (isNotEmpty(extension) ? (extension.size() - 1) : 0)));
+               } else {
+                       directory = path;
+               }
+       }
+
+       void splitFileName(const std::string &path,
+                       std::string &baseName, std::string &extension)
+       {
+               baseName = extractFileName(path);
+               if (isNotEmpty(baseName)) {
+                       extension = extractExtension(baseName);
+                       if (isNotEmpty(extension)) {
+                               baseName.resize(baseName.size() - extension.size() - 1);
+                       }
+               } else {
+                       extension.clear();
+               }
+       }
+
+       std::string makeUniqueFilePath(const std::string &srcPath,
+                       const std::string &dstDir)
+       {
+               std::string baseName;
+               std::string extension;
+               splitFileName(srcPath, baseName, extension);
+
+               std::string result;
+               result.reserve(dstDir.size() + baseName.size() +
+                               extension.size() + impl::UNIQUE_PATH_RESERVE);
+
+               result = dstDir;
+               if (isNotEmpty(result) && (result.back() != '/')) {
+                       result += '/';
+               }
+               result += baseName;
+
+               const auto baseSize = result.size();
+
+               for (int counter = 2; ; ++counter) {
+                       if (isNotEmpty(extension)) {
+                               result += '.';
+                               result += extension;
+                       }
+                       if (!ecore_file_exists(result.c_str())) {
+                               break;
+                       }
+                       result.resize(baseSize);
+                       result += " (";
+                       result += std::to_string(counter);
+                       result += ')';
+               }
+
+               return result;
+       }
+}}
index 05abb4a5fdd1b5c576cc1b8a7ea3d6e1433ddceb..29da4d80b7cb2af18e2c033eae531943e1b781eb 100644 (file)
@@ -26,8 +26,26 @@ namespace gallery {
        MediaType toMediaType(media_content_type_e contentType);
 
        ucl::Mutex &getMediaMutex();
+
+       ucl::Result getInternalStorageId(int &result);
 }
 
+namespace gallery { namespace util {
+
+       std::string extractFileName(const std::string &path);
+
+       std::string extractFileExtension(const std::string &name);
+
+       void splitFilePath(const std::string &path, std::string &directory,
+                       std::string &baseName, std::string &extension);
+
+       void splitFileName(const std::string &path,
+                       std::string &baseName, std::string &extension);
+
+       std::string makeUniqueFilePath(const std::string &srcPath,
+                       const std::string &dstDir);
+}}
+
 #include "helpers.hpp"
 
 #endif // __GALLERY_MODEL_HELPERS_H__
index fef4dce8c96d8e44e62bceebd8cf6f81dd7f18e0..3e8a104f247d2d097d4a09ce004d8768b2114458 100644 (file)
@@ -181,15 +181,12 @@ namespace gallery {
        Result Instance::handleAppControl(app_control_h appControl)
        {
                std::string operation;
-               if (!getProperty(appControl, app_control_get_operation, operation)) {
-                       ELOG("app_control_get_operation() failed!");
-               }
+               FAIL_LOG(util::getNz(app_control_get_operation, operation, appControl),
+                       "app_control_get_operation() failed!");
 
                app_control_launch_mode_e mode = APP_CONTROL_LAUNCH_MODE_SINGLE;
-               if (!getProperty(appControl, app_control_get_launch_mode, mode, true)) {
-                       ELOG("app_control_get_launch_mode() failed!");
-                       mode = APP_CONTROL_LAUNCH_MODE_SINGLE;
-               }
+               FAIL_LOG(util::get(app_control_get_launch_mode, mode, appControl),
+                       "app_control_get_launch_mode() failed!");
 
                DLOG("operation: %s; mode: %d;", operation.c_str(), mode);
 
@@ -232,10 +229,8 @@ namespace gallery {
 
                if (operation == APP_CONTROL_OPERATION_VIEW) {
                        std::string uri;
-                       if (!getProperty(appControl, app_control_get_uri, uri)) {
-                               ELOG("app_control_get_uri() failed!");
-                               return RES_FAIL;
-                       }
+                       FAIL_RETURN(util::getNz(app_control_get_uri, uri, appControl),
+                               "app_control_get_uri() failed!");
                        createViewerPage(uri);
                } else {
                        WLOG("Operation not supported for current mode!");