Click here to Skip to main content
15,867,308 members
Articles / Desktop Programming / Win32

The GOD : Google, Onedrive and Dropbox Access in One REST Windows Library!

Rate me:
Please Sign up or sign in to vote.
4.67/5 (11 votes)
30 May 2019CPOL4 min read 22.9K   372   30   6
C++ dir, upload, download and management library

GOD class is now part of my RGF library.

Introduction

The time has come to put my good REST Library to use. Here is a simple, yet powerful library that provides an abstraction class to use Google Drive, OneDrive and DropBox services. I use them in my own BAR app.

Background

In this article, I use some simple extensions to known elements, like the ystring (a wstring that can also return an ANSI string in UTF-8), TEVENT<> (a wrapper on HEVENT), and XSOCKET, a wrapper of SOCKET with SSL support - all of these are simple to understand and use and they will be discussed in later articles or have been discussed in previous articles. In addition, Hong Jiang's jsonxx library is used.

You only need to include god.h to your projects, along with jsonxx.h, sync.h, rest.h, xsocket.h and ystring.h.

The zip file contains a solution and you can uncomment main.cpp lines to download and upload files.

Abstract DRIVE Class

The entire thing is based on an abstract class called DRIVE, a descendant of my REST class:

C++
class DRIVE : public REST
    {
    protected:

        ystring cid;
        ystring secret;
        jsonxx::Object j;
        int port = 9932;
        TEVENT<> ev;
        XSOCKET x;
        vector<char> nd;
      
    public:

        DRIVE(const char* ccid = 0, const char* ssid = 0,int HostPort = 9932)
            {
            SetClient(ccid, ssid,HostPort);
            }
        virtual void SetClient(const char* ccid = 0, const char* ssid = 0,int HostPort = 9932)
            {
            if (ccid)
                cid = ccid;
            if (ssid)
                secret = ssid;
            port = HostPort;
            }
        virtual string jsonreturn(ihandle& r)
            {
            vector<char> out;
            ReadToMemory(r, out);
            out.resize(out.size() + 1);
            char* p = (char*)out.data();
            return p;
            }

        virtual int Auth(vector<string>&) = 0;
        virtual string CreateFolder(const char* fn,const char*pid) = 0;
        virtual string GetRootFolderID() = 0;
        virtual string IDFromPath(const char* Path,bool CreateIfNotExists = false) = 0;
        virtual string dir(const char* Path = 0,bool IsRDir = false) = 0;
        virtual string ItemProps(const char* id) = 0;
        virtual string SetProperty(const char* id, const char* n, const char* v) = 0;
        virtual HRESULT Download(const char* fid, HANDLE hF, vector<char>* arr, 
        unsigned long long from = 0, unsigned long long to = (unsigned long long) - 1, 
        std::function<HRESULT(unsigned long long, unsigned long long, void*)> fx = 0, 
        void* lp = 0) = 0;
        virtual HRESULT Upload(bool Resumable,HANDLE hX, vector<char>* arr,
        const char* folderid, const char* filename, string& resumedata,string& 
        returndata,std::function<HRESULT(unsigned long long f, unsigned long long t, 
        void* lp)> fx = 0, void* lp = 0) = 0;
        virtual string Delete(const char *rp,const char* fid, bool Trash = false) = 0;
        virtual HRESULT HashItem(const char* id, string& Hash, ALG_ID& HashAlg) = 0;
    };

Constructor

The problem of all these libraries is that they require some manual "OK" from the user to initially allow access, and this has to be done over a browser. Therefore, each constructor takes, along with the "client id" and "client secret" parameters, a TCP port in which a termporarily web server is listening.

C++
DRIVE(const char* ccid = 0, const char* ssid = 0,int HostPort = 9932);

Authentication

C++
virtual int Auth(vector<string>&);

You pass a vector<string> to this function, containing authentication token values. If first time, you pass an empty vector. On return, this function returns:

  • 0 - Failed. End of library usage
  • 1 - Succeeded
  • 2 - Succeeded, new tokens have arrived, you should now save the contains of this vector for further usage.

Normally, an access token, a refresh token and a code are returned. Auth() on first time will create a listening socket, then open a web page with an authorization URL for the user to click "I accept", then, a code will be returned to the application, which is then used to claim an access token.

Files and Folders

In Google drive and one drive, files and folders are represented by IDs, where, in dropbox, files are represented by file names. To ensure compatibility, the library uses the "id" naming no matter what.

Getting Information

C++
string IDFromPath(const char* Path,bool CreateIfNotExists = false);

This function returns an ID from a given path name. If this item does not exist and CreateIfNotExists is true, the function creates a directory at that path.

C++
string GetRootFolderID();

This function returns the ID of the "root" folder.

C++
string dir(const char* Path = 0,bool IsRDir = false);

This function returns the directory (as a json string) for the given path. If IsRDir is true, then the Path is assumed to be an ID (if not, the function IDFromPath is used to convert the path to an ID).

Create a Folder

C++
virtual string CreateFolder(const char* fn,const char*pid);

Creates a folder with a given file name on a parent directory with ID pid. Returns the describing json on success.

Delete an Item

C++
string Delete(const char *rp,const char* fid, bool Trash = false);

Deletes an item. In Google and Onedrive, only the second parameter is used (the ID), while, in DropBox, only the first parameter (the path) is used. Trash is true if the file is to be sent to the recycle bin.

When you call ONEDRIVE::Delete or DROPBOX::Delete with Trash set to false, E_NOTIMPL is returned. These drives only allow recycling from the API, not direct delete.

Hash an Item

C++
HRESULT HashItem(const char* id, string& Hash, ALG_ID& HashAlg);

Hashes a remote item (Google Drive only), returning a CALG_MD5 string.

Download Data

C++
HRESULT Download(const char* fid, HANDLE hF, vector<char>* arr, 
unsigned long long from = 0, unsigned long long to = (unsigned long long) - 1, 
std::function<HRESULT(unsigned long long, unsigned long long, void*)> fx = 0, 
void* lp = 0) = 0;

Accepting as parameters:

  • The ID of the file to download
  • Either a HANDLE to save to file, or a vector<char> to save to a buffer
  • from/to, download range (pass 0,-1 for entire stream)
  • A callback and its param for progress

This function downloads the specified item.

Uploading Data

C++
HRESULT Upload(bool Resumable,HANDLE hX, vector<char>* arr,const char* folderid, 
const char* filename, string& resumedata,string& returndata,std::function<HRESULT
(unsigned long long f, unsigned long long t, void* lp)> fx = 0, void* lp = 0) = 0;

Accepting as parameters:

  • A flag to indicate if resumable uploads should be supported (Google Drive only)
  • A handle or a vector to read data
  • The parent folder's ID
  • The new file name
  • A callback and its param for progress.

This function uploads data.

For Google drive, you can use either UploadOnce():

C++
HRESULT UploadOnce(HANDLE hX, vector<char>* arr, const char* folderid, 
const char* filename, string& returndata, std::function<HRESULT
(unsigned long long f, unsigned long long t, void* lp)> fx = 0, void* lp = 0)

or you can use BeginResumable():

C++
HRESULT BeginResumable(HANDLE hX, vector<char>* arr, const char* folderid, 
const char* filename, string& returndata, string& resumedata,std::function<HRESULT
(unsigned long long f, unsigned long long t, void* lp)> fx = 0, void* lp = 0);

If this function fails, there may be resume-related data returned. In this case, you can call again the ContinueResumable():

C++
HRESULT ContinueResumable(HANDLE hX, vector<char>* arr, const char* folderid, 
const char* filename, string& returndata, string& resumedata, 
std::function<HRESULT(unsigned long long f, unsigned long long t, void* lp)> fx = 0, 
void* lp = 0);

Which can resume the upload.

History

  • 3-2-2017: First release

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer
Greece Greece
I'm working in C++, PHP , Java, Windows, iOS, Android and Web (HTML/Javascript/CSS).

I 've a PhD in Digital Signal Processing and Artificial Intelligence and I specialize in Pro Audio and AI applications.

My home page: https://www.turbo-play.com

Comments and Discussions

 
QuestionHi. Error while compile VS 2019 Pin
As F24-Apr-23 23:18
As F24-Apr-23 23:18 
QuestionProvide an example for what to put into <onedrive u="" p="" t1="" t2=""/> Pin
Alexandru Matei15-Aug-21 10:15
Alexandru Matei15-Aug-21 10:15 
GeneralMy vote of 3 Pin
evry1falls3-May-20 9:43
evry1falls3-May-20 9:43 
PraiseGreat! Pin
koothkeeper31-May-19 6:14
professionalkoothkeeper31-May-19 6:14 
QuestionIssue in case of onedrive Pin
Member 106486081-Apr-19 0:33
Member 106486081-Apr-19 0:33 
AnswerRe: Issue in case of onedrive Pin
Michael Chourdakis30-May-19 2:50
mvaMichael Chourdakis30-May-19 2:50 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.