[vlc-devel] [PATCH] cloudstorage module, with folders browsing and keystore

Victorien Le Couviour--Tuffet victorien.lecouviour.tuffet at gmail.com
Wed Apr 26 19:28:17 CEST 2017


From: William Ung <williamung at msn.com>

---
 configure.ac                    |   2 +-
 include/vlc_keystore.h          |   7 +-
 modules/access/Makefile.am      |   7 ++
 modules/access/cloudstorage.cpp | 264 ++++++++++++++++++++++++++++++++++++++++
 src/libvlccore.sym              |   1 +
 src/misc/keystore.c             |   4 +-
 6 files changed, 280 insertions(+), 5 deletions(-)
 create mode 100644 modules/access/cloudstorage.cpp

diff --git a/configure.ac b/configure.ac
index fde2dea..a0538a1 100644
--- a/configure.ac
+++ b/configure.ac
@@ -2087,7 +2087,7 @@ dnl
 dnl  matroska demux plugin
 dnl
 PKG_ENABLE_MODULES_VLC([MATROSKA], [mkv], [libebml libmatroska], [MKV format support], [auto])
-
+PKG_ENABLE_MODULES_VLC([CLOUDSTORAGE], [cloudstorage], [libcloudstorage], [cloudstorage access], [auto])
 dnl
 dnl  modplug demux plugin
 dnl
diff --git a/include/vlc_keystore.h b/include/vlc_keystore.h
index 0af15eb..d081877 100644
--- a/include/vlc_keystore.h
+++ b/include/vlc_keystore.h
@@ -15,7 +15,7 @@
  *
  * You should have received a copy of the GNU Lesser General Public License
  * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
+ * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.obj
  *****************************************************************************/
 
 #ifndef VLC_KEYSTORE_H
@@ -72,6 +72,9 @@ struct vlc_keystore_entry
     size_t              i_secret_len;
 };
 
+VLC_API vlc_keystore *
+get_memory_keystore(vlc_object_t *p_parent);
+
 /**
  * Create a keystore object
  *
@@ -117,7 +120,7 @@ vlc_keystore_store(vlc_keystore *p_keystore,
 
 /**
  * Find all entries that match a set of key/values
- * 
+ *
  * @param ppsz_values set of key/values, see vlc_keystore_key, any values can
  * be NULL
  * @param pp_entries list of found entries. To be released with
diff --git a/modules/access/Makefile.am b/modules/access/Makefile.am
index dd485a2..6b21a90 100644
--- a/modules/access/Makefile.am
+++ b/modules/access/Makefile.am
@@ -313,6 +313,13 @@ endif
 
 ### Network streams ###
 
+libcloudstorage_plugin_la_SOURCES = access/cloudstorage/cloudstorage.cpp access/cloudstorage/cloudstorage.h access/cloudstorage/callback.h
+libcloudstorage_plugin_la_CXXFLAGS = $(CXXFLAGS_cloudstorage) $(AM_CXXFLAGS)
+libcloudstorage_plugin_la_LIBADD = $(LIBS_cloudstorage)
+libcloudstorage_plugin_la_LDFLAGS = $(AM_LDFLAGS) -rpath '$(accessdir)'
+access_LTLIBRARIES += $(LTLIBcloudstorage)
+EXTRA_LTLIBRARIES += libcloudstorage_plugin.la
+
 libftp_plugin_la_SOURCES = access/ftp.c
 libftp_plugin_la_LIBADD = $(SOCKET_LIBS)
 access_LTLIBRARIES += libftp_plugin.la
diff --git a/modules/access/cloudstorage.cpp b/modules/access/cloudstorage.cpp
new file mode 100644
index 0000000..a3ea31d
--- /dev/null
+++ b/modules/access/cloudstorage.cpp
@@ -0,0 +1,264 @@
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif /* HAVE_CONFIG_H */
+
+#include <cstdarg>
+#include <cstdlib>
+#include <iostream>
+#include <fstream>
+#include <mutex>
+#include <thread>
+#include <vector>
+#include <string>
+#include <memory>
+#include <condition_variable>
+
+#include <ICloudProvider.h>
+#include <ICloudStorage.h>
+#include <IItem.h>
+#include <IRequest.h>
+
+#include <vlc_common.h>
+#include <vlc_plugin.h>
+#include <vlc_access.h>
+#include <vlc_services_discovery.h>
+#include <vlc_keystore.h>
+
+using namespace cloudstorage;
+using cloudstorage::ICloudProvider;
+using cloudstorage::IDownloadFileCallback;
+using cloudstorage::IItem;
+
+static int    Open(vlc_object_t *);
+static void   Close(vlc_object_t *);
+static int    readDir(stream_t *, input_item_node_t *);
+
+vlc_module_begin()
+set_shortname(N_("cloudstorage"))
+set_capability("access", 0)
+set_description(N_("cloud input"))
+set_category(CAT_INPUT)
+set_subcategory(SUBCAT_INPUT_ACCESS)
+set_callbacks(Open, Close)
+
+vlc_module_end()
+
+/*
+**  private struct
+*/
+
+struct				access_sys_t
+{
+  using Pointer = std::shared_ptr<access_sys_t>;
+
+  ICloudProvider::Pointer	provider_;
+  std::string			provider_name_;
+  std::string			token_;
+
+  vlc_keystore   *p_keystore_;
+  char *ppsz_values[KEY_MAX];
+
+  IItem::Pointer		current_item_;
+  std::vector<std::string>	directory_stack_;
+  std::vector<IItem::Pointer> directory_list_;
+
+  ICloudProvider::ListDirectoryRequest::Pointer	list_directory_request_;
+
+  std::mutex			stream_mutex_;
+  std::condition_variable	stream_cv_;
+
+  access_sys_t(vlc_object_t *);
+};
+
+/*
+**  Provider Callback
+*/
+
+class  			Callback : public ICloudProvider::ICallback {
+public:
+  Callback(access_sys_t *sys)
+  {
+    p_sys = sys;
+  }
+
+  Status			userConsentRequired(const ICloudProvider& provider) override
+  {
+    std::cout << "User ConsentRequired at : " << provider.authorizeLibraryUrl() << std::endl;
+    return Status::WaitForAuthorizationCode;
+  }
+
+  void        accepted(const ICloudProvider& provider) override
+  {
+    p_sys->token_ = provider.token();
+    vlc_keystore_remove(p_sys->p_keystore_, p_sys->ppsz_values);
+    vlc_keystore_store(p_sys->p_keystore_, p_sys->ppsz_values, (const uint8_t *)p_sys->token_.c_str(), p_sys->token_.size(), p_sys->provider_name_.c_str());
+    std::cout << "accepted" << std::endl;
+  }
+
+  void        declined(const ICloudProvider& provider) override
+  {
+    std::cout << "declined" << std::endl;
+  }
+
+  void	      error(const ICloudProvider& provider, const std::string& desc) override
+  {
+    std::cout << "an error occured : " << desc  << std::endl;
+  }
+  access_sys_t    *p_sys;
+};
+
+static void       get_ppsz_values(char *ppsz_values[KEY_MAX], std::string provider_name)
+{
+  ppsz_values[KEY_PROTOCOL] = "cloudstorage";
+  ppsz_values[KEY_USER] = "cloudstorage user";
+  ppsz_values[KEY_SERVER] = "cloudstorage";
+}
+
+access_sys_t::access_sys_t(vlc_object_t *p_this)
+{
+  vlc_keystore_entry  *p_entries;
+
+  p_keystore_ = get_memory_keystore(p_this);
+  provider_name_ = "box";
+  provider_ = cloudstorage::ICloudStorage::create()->provider(provider_name_);
+  if (!provider_)
+    return;
+  VLC_KEYSTORE_VALUES_INIT(ppsz_values);
+  get_ppsz_values(ppsz_values, provider_name_);
+
+  if (vlc_keystore_find(p_keystore_, ppsz_values, &p_entries) > 0)
+  {
+    std::cout << "cacaaaaa" << '\n';
+    token_ = (char *)p_entries[0].p_secret;
+  }
+  provider_->initialize({token_, std::unique_ptr<Callback>(new Callback(this)), nullptr, nullptr, nullptr, {}});
+  current_item_ = provider_->rootDirectory();
+}
+
+static int               Control(stream_t *p_access, int i_query, va_list args)
+{
+  switch (i_query)
+    {
+    case STREAM_IS_DIRECTORY:
+      *va_arg(args, bool *) = p_access->pf_readdir == readDir;
+      break;
+
+    default:
+      return access_vaDirectoryControlHelper( p_access, i_query, args );
+    }
+
+  return VLC_SUCCESS;
+}
+
+static int                add_item(struct access_fsdir *p_fsdir, stream_t *p_access, IItem::Pointer item)
+{
+  int                     i_type;
+  access_sys_t            *p_sys = (access_sys_t*)p_access->p_sys;
+  ICloudProvider::Pointer provider = p_sys->provider_;
+
+  item->type() == IItem::FileType::Directory ? i_type = ITEM_TYPE_DIRECTORY : i_type = ITEM_TYPE_FILE;
+   if (i_type == ITEM_TYPE_FILE)
+   {
+     item = provider->getItemDataAsync(item->id())->result();
+     return access_fsdir_additem(p_fsdir, item->url().c_str(), item->filename().c_str(), i_type, ITEM_NET);
+   }
+   else
+   {
+     std::string          url = p_access->psz_url + item->filename() + "/";
+    return access_fsdir_additem(p_fsdir, url.c_str(), item->filename().c_str(), i_type, ITEM_NET);
+   }
+}
+
+static int                readDir(stream_t *p_access, input_item_node_t *p_node)
+{
+  access_sys_t            *p_sys = (access_sys_t*)p_access->p_sys;
+  struct access_fsdir     fsdir;
+
+
+  p_sys->list_directory_request_ = p_sys->provider_->listDirectoryAsync(p_sys->current_item_);
+  p_sys->directory_list_ = p_sys->list_directory_request_->result();
+  access_fsdir_init(&fsdir, p_access, p_node);
+
+  auto finish = [&](int error)
+  {
+    access_fsdir_finish(&fsdir, error);
+    return error;
+  };
+
+  for (auto &i : p_sys->directory_list_)
+    if (add_item(&fsdir, p_access, i))
+      return finish(VLC_EGENERIC);
+  return finish(VLC_SUCCESS);
+}
+
+std::vector<std::string>        parseUrl(std::string url)
+{
+  std::vector<std::string> v;
+
+  url = url.substr(15);
+  for (size_t i = 0; i < url.size(); ++i)
+  {
+    if (url[i] == '/')
+    {
+      v.push_back(url.substr(0, i));
+      url = url.substr(i + 1);
+    }
+  }
+  return v;
+}
+
+static int                  getDir(stream_t *p_access, input_item_node_t *p_node)
+{
+  access_sys_t            *p_sys = (access_sys_t*)p_access->p_sys;
+
+  if (strcmp(p_access->psz_url, "cloudstorage://") == 0)
+    readDir(p_access, p_node);
+  else
+  {
+    p_sys->directory_stack_ = parseUrl(p_access->psz_url);
+    for (auto &name : p_sys->directory_stack_)
+    {
+      p_sys->list_directory_request_ = p_sys->provider_->listDirectoryAsync(p_sys->current_item_);
+      p_sys->directory_list_ = p_sys->list_directory_request_->result();
+      for (auto &item : p_sys->directory_list_)
+        if (item->filename() == name)
+        {
+          p_sys->current_item_ = item;
+          break;
+        }
+    }
+    readDir(p_access, p_node);
+  }
+  return VLC_SUCCESS;
+}
+
+static int                Open(vlc_object_t *p_this)
+{
+  access_t                *p_access = (access_t*)p_this;
+  access_sys_t        	  *p_sys;
+
+  p_access->p_sys = p_sys = new access_sys_t(p_this);
+  if (p_sys == nullptr)
+    return VLC_ENOMEM;
+  p_access->pf_control = Control;
+  p_access->pf_readdir = getDir;
+  if (p_access->pf_control == nullptr
+    || p_access->pf_readdir == nullptr
+    || p_sys->p_keystore_ == nullptr)
+    goto error;
+  return VLC_SUCCESS;
+
+  error:
+  Close(p_this);
+  return VLC_EGENERIC;
+}
+
+static void           Close(vlc_object_t *p_this)
+{
+  access_t            *p_access = (access_t*)p_this;
+  access_sys_t     	  *p_sys = (access_sys_t*)p_access->p_sys;
+
+std::cout << "Close" << '\n';
+  delete(p_sys);
+  return;
+}
diff --git a/src/libvlccore.sym b/src/libvlccore.sym
index 4cb7a22..25d01df 100644
--- a/src/libvlccore.sym
+++ b/src/libvlccore.sym
@@ -591,6 +591,7 @@ vlc_ngettext
 vlc_iconv
 vlc_iconv_close
 vlc_iconv_open
+get_memory_keystore
 vlc_keystore_create
 vlc_keystore_release
 vlc_keystore_find
diff --git a/src/misc/keystore.c b/src/misc/keystore.c
index 02537f0..c6096cf 100644
--- a/src/misc/keystore.c
+++ b/src/misc/keystore.c
@@ -101,7 +101,7 @@ vlc_keystore_store(vlc_keystore *p_keystore,
 }
 
 unsigned int
-vlc_keystore_find(vlc_keystore *p_keystore, 
+vlc_keystore_find(vlc_keystore *p_keystore,
                   const char * const ppsz_values[KEY_MAX],
                   vlc_keystore_entry **pp_entries)
 {
@@ -148,7 +148,7 @@ libvlc_InternalKeystoreClean(libvlc_int_t *p_libvlc)
     }
 }
 
-static vlc_keystore *
+vlc_keystore *
 get_memory_keystore(vlc_object_t *p_obj)
 {
     return libvlc_priv(p_obj->obj.libvlc)->p_memory_keystore;
-- 
2.7.4

_______________________________________________
vlc-devel mailing list
To unsubscribe or modify your subscription options:
https://mailman.videolan.org/listinfo/vlc-devel


More information about the vlc-devel mailing list