[vlc-devel] [PATCH] cloudstorage module, with folders browsing and keystore
William Ung
williamung at msn.com
Wed Apr 19 18:24:43 CEST 2017
---
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
More information about the vlc-devel
mailing list