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

Victorien Le Couviour victorien.lecouviour.tuffet at gmail.com
Wed Apr 26 17:34:27 CEST 2017


Sorry did not send that on purpose, it appears the mailbox decided to send
it to everybody instead of just the addressee. My bad.

2017-04-26 19:28 GMT+02:00 Victorien Le Couviour--Tuffet <
victorien.lecouviour.tuffet at gmail.com>:

> 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
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mailman.videolan.org/pipermail/vlc-devel/attachments/20170426/a506b4e5/attachment.html>


More information about the vlc-devel mailing list