├── test
├── Test.res
├── Test.dpr
├── DropboxManager.Tests.pas
└── Test.dproj
├── .gitattributes
├── README.md
├── .gitignore
├── src
├── DropboxApi.pas
├── DropboxApi.Routes.pas
├── DropboxApi.Persister.pas
├── DropboxManager.pas
├── DropboxApi.Requests.pas
└── DropboxApi.Data.pas
└── LICENSE
/test/Test.res:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CleverComponents/DropBox-Delphi-API/HEAD/test/Test.res
--------------------------------------------------------------------------------
/.gitattributes:
--------------------------------------------------------------------------------
1 | # Set the default behavior, in case people don't have core.autocrlf set.
2 | * text=auto
3 |
4 | # Denote all files that are truly binary and should not be modified.
5 | *.dat binary
6 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Dropbox API for Delphi
2 |
3 |
4 |
5 | The Dropbox API library for Delphi allows working with Dropbox directory using official Dropbox API v2.
6 |
7 | The library includes a powerful OAuth 2.0 support with a consistent interface. You can use the Dropbox API for Delphi to download and upload files, manage files and folders on Dropbox directory.
8 |
9 | This article describes how connect to Dropbox account in Delphi, download and upload files programmatically, create remote folders and save an URL into a file in user's Dropbox.
10 |
11 | [Read the article](https://www.clevercomponents.com/articles/article041/)
12 |
--------------------------------------------------------------------------------
/test/Test.dpr:
--------------------------------------------------------------------------------
1 | program Test;
2 |
3 | uses
4 | Vcl.Forms,
5 | TestFrameWork,
6 | GUITestRunner,
7 | DropboxManager.Tests in 'DropboxManager.Tests.pas',
8 | clJsonSerializer in '..\..\JsonSerializer\json\clJsonSerializer.pas',
9 | clJsonSerializerBase in '..\..\JsonSerializer\json\clJsonSerializerBase.pas',
10 | DropboxManager in '..\src\DropboxManager.pas',
11 | DropboxApi.Data in '..\src\DropboxApi.Data.pas',
12 | DropboxApi in '..\src\DropboxApi.pas',
13 | DropboxApi.Persister in '..\src\DropboxApi.Persister.pas',
14 | DropboxApi.Routes in '..\src\DropboxApi.Routes.pas',
15 | DropboxApi.Requests in '..\src\DropboxApi.Requests.pas',
16 | clJsonParser in '..\..\JsonSerializer\json\clJsonParser.pas';
17 |
18 | {$R *.res}
19 |
20 | begin
21 | Application.Initialize;
22 | GUITestRunner.RunRegisteredTests;
23 | end.
24 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Uncomment these types if you want even more clean repository. But be careful.
2 | # It can make harm to an existing project source. Read explanations below.
3 | #
4 | # Resource files are binaries containing manifest, project icon and version info.
5 | # They can not be viewed as text or compared by diff-tools. Consider replacing them with .rc files.
6 | #*.res
7 | #
8 | # Type library file (binary). In old Delphi versions it should be stored.
9 | # Since Delphi 2009 it is produced from .ridl file and can safely be ignored.
10 | #*.tlb
11 | #
12 | # Diagram Portfolio file. Used by the diagram editor up to Delphi 7.
13 | # Uncomment this if you are not using diagrams or use newer Delphi version.
14 | #*.ddp
15 | #
16 | # Visual LiveBindings file. Added in Delphi XE2.
17 | # Uncomment this if you are not using LiveBindings Designer.
18 | #*.vlb
19 | #
20 | # Deployment Manager configuration file for your project. Added in Delphi XE2.
21 | # Uncomment this if it is not mobile development and you do not use remote debug feature.
22 | #*.deployproj
23 | #
24 | # C++ object files produced when C/C++ Output file generation is configured.
25 | # Uncomment this if you are not using external objects (zlib library for example).
26 | #*.obj
27 | #
28 |
29 | # Delphi compiler-generated binaries (safe to delete)
30 | *.exe
31 | *.dll
32 | *.bpl
33 | *.bpi
34 | *.dcp
35 | *.so
36 | *.apk
37 | *.drc
38 | *.map
39 | *.dres
40 | *.rsm
41 | *.tds
42 | *.dcu
43 | *.lib
44 | *.a
45 | *.o
46 | *.ocx
47 |
48 | # Delphi autogenerated files (duplicated info)
49 | *.cfg
50 | *.hpp
51 | *Resource.rc
52 |
53 | # Delphi local files (user-specific info)
54 | *.local
55 | *.identcache
56 | *.projdata
57 | *.tvsconfig
58 | *.dsk
59 |
60 | # Delphi history and backups
61 | __history/
62 | __recovery/
63 | *.~*
64 |
65 | # Castalia statistics file (since XE7 Castalia is distributed with Delphi)
66 | *.stat
67 |
--------------------------------------------------------------------------------
/src/DropboxApi.pas:
--------------------------------------------------------------------------------
1 | {
2 | Copyright (C) 2017 by Clever Components
3 |
4 | Author: Sergey Shirokov
5 |
6 | Website: www.CleverComponents.com
7 |
8 | This file is part of Dropbox Client Library for Delphi.
9 |
10 | Dropbox Client Library for Delphi is free software:
11 | you can redistribute it and/or modify it under the terms of
12 | the GNU Lesser General Public License version 3
13 | as published by the Free Software Foundation and appearing in the
14 | included file COPYING.LESSER.
15 |
16 | Dropbox Client Library for Delphi is distributed in the hope
17 | that it will be useful, but WITHOUT ANY WARRANTY; without even the
18 | implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
19 | See the GNU Lesser General Public License for more details.
20 |
21 | You should have received a copy of the GNU Lesser General Public License
22 | along with Dropbox Client Library. If not, see .
23 |
24 | The current version of Dropbox Client Client Library for Delphi needs for
25 | the non-free library Clever Internet Suite. This is a drawback,
26 | and we suggest the task of changing
27 | the program so that it does the same job without the non-free library.
28 | Anyone who thinks of doing substantial further work on the program,
29 | first may free it from dependence on the non-free library.
30 | }
31 |
32 | unit DropboxApi;
33 |
34 | interface
35 |
36 | uses
37 | System.Classes, System.SysUtils, clJsonSerializerBase, DropboxApi.Data;
38 |
39 | type
40 | EDropboxException = class(Exception)
41 | strict private
42 | FError: TError;
43 |
44 | procedure SetError(const Value: TError);
45 | function GetErrorSummary: string;
46 | procedure SetErrorSummary(const Value: string);
47 | public
48 | constructor Create; overload;
49 | constructor Create(AError: TError); overload;
50 | destructor Destroy; override;
51 |
52 | [TclJsonString('error_summary')]
53 | property ErrorSummary: string read GetErrorSummary write SetErrorSummary;
54 |
55 | [TclJsonProperty('error')]
56 | property Error: TError read FError write SetError;
57 | end;
58 |
59 | TCredential = class abstract
60 | public
61 | function GetAuthorization: string; virtual; abstract;
62 | function RefreshAuthorization: string; virtual; abstract;
63 | procedure RevokeAuthorization; virtual; abstract;
64 | procedure Abort; virtual; abstract;
65 | end;
66 |
67 | TJsonSerializer = class abstract
68 | public
69 | function JsonToException(const AJson: string): EDropboxException; virtual; abstract;
70 | function ExceptionToJson(E: EDropboxException): string; virtual; abstract;
71 |
72 | function JsonToObject(AType: TClass; const AJson: string): TObject; virtual; abstract;
73 | function ObjectToJson(AObject: TObject): string; virtual; abstract;
74 | end;
75 |
76 | TServiceInitializer = class;
77 |
78 | THttpClient = class abstract
79 | strict private
80 | FInitializer: TServiceInitializer;
81 | strict protected
82 | function GetStatusCode: Integer; virtual; abstract;
83 | public
84 | constructor Create(AInitializer: TServiceInitializer);
85 |
86 | function RpcEndPointRequest(const AUri: string; const ARequest: string): string; virtual; abstract;
87 | function ContentUploadEndPointRequest(const AUri: string; const ARequestHeader: string; ABody: TStream): string; virtual; abstract;
88 | function ContentDownloadEndPointRequest(const AUri: string; const ARequestHeader: string; ABody: TStream): string; virtual; abstract;
89 | procedure Abort; virtual; abstract;
90 |
91 | property Initializer: TServiceInitializer read FInitializer;
92 | property StatusCode: Integer read GetStatusCode;
93 | end;
94 |
95 | TServiceInitializer = class abstract
96 | strict private
97 | FApplicationName: string;
98 | FCredential: TCredential;
99 | strict protected
100 | function GetHttpClient: THttpClient; virtual; abstract;
101 | function GetJsonSerializer: TJsonSerializer; virtual; abstract;
102 | public
103 | constructor Create(ACredential: TCredential; const ApplicationName: string);
104 | destructor Destroy; override;
105 |
106 | property HttpClient: THttpClient read GetHttpClient;
107 | property JsonSerializer: TJsonSerializer read GetJsonSerializer;
108 | property Credential: TCredential read FCredential;
109 | property ApplicationName: string read FApplicationName;
110 | end;
111 |
112 | TService = class
113 | strict private
114 | FInitializer: TServiceInitializer;
115 | public
116 | constructor Create(AInitializer: TServiceInitializer);
117 | destructor Destroy; override;
118 |
119 | procedure Abort;
120 |
121 | property Initializer: TServiceInitializer read FInitializer;
122 | end;
123 |
124 | TServiceRequest = class abstract
125 | strict private
126 | FService: TService;
127 | public
128 | constructor Create(AService: TService);
129 |
130 | function Execute: TResponse; virtual; abstract;
131 |
132 | property Service: TService read FService;
133 | end;
134 |
135 | resourcestring
136 | cUnspecifiedError = 'Unspecified error';
137 |
138 | implementation
139 |
140 | { EDropboxException }
141 |
142 | constructor EDropboxException.Create;
143 | begin
144 | inherited Create(cUnspecifiedError);
145 | end;
146 |
147 | constructor EDropboxException.Create(AError: TError);
148 | begin
149 | inherited Create(cUnspecifiedError);
150 | SetError(AError);
151 | end;
152 |
153 | destructor EDropboxException.Destroy;
154 | begin
155 | SetError(nil);
156 | inherited Destroy();
157 | end;
158 |
159 | function EDropboxException.GetErrorSummary: string;
160 | begin
161 | Result := Message;
162 | end;
163 |
164 | procedure EDropboxException.SetError(const Value: TError);
165 | begin
166 | FError.Free();
167 | FError := Value;
168 | end;
169 |
170 | procedure EDropboxException.SetErrorSummary(const Value: string);
171 | begin
172 | Message := Value;
173 | end;
174 |
175 | { THttpClient }
176 |
177 | constructor THttpClient.Create(AInitializer: TServiceInitializer);
178 | begin
179 | inherited Create();
180 | FInitializer := AInitializer;
181 | end;
182 |
183 | { TServiceInitializer }
184 |
185 | constructor TServiceInitializer.Create(ACredential: TCredential; const ApplicationName: string);
186 | begin
187 | inherited Create();
188 |
189 | FCredential := ACredential;
190 | FApplicationName := ApplicationName;
191 |
192 | Assert(FCredential <> nil);
193 | end;
194 |
195 | destructor TServiceInitializer.Destroy;
196 | begin
197 | FCredential.Free();
198 | inherited Destroy();
199 | end;
200 |
201 | { TService }
202 |
203 | procedure TService.Abort;
204 | begin
205 | FInitializer.Credential.Abort();
206 | FInitializer.HttpClient.Abort();
207 | end;
208 |
209 | constructor TService.Create(AInitializer: TServiceInitializer);
210 | begin
211 | inherited Create();
212 | FInitializer := AInitializer;
213 | Assert(FInitializer <> nil);
214 | end;
215 |
216 | destructor TService.Destroy;
217 | begin
218 | FInitializer.Free();
219 | inherited Destroy();
220 | end;
221 |
222 | { TServiceRequest }
223 |
224 | constructor TServiceRequest.Create(AService: TService);
225 | begin
226 | inherited Create();
227 | FService := AService;
228 | end;
229 |
230 | end.
231 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | GNU LESSER GENERAL PUBLIC LICENSE
2 | Version 3, 29 June 2007
3 |
4 | Copyright (C) 2007 Free Software Foundation, Inc.
5 | Everyone is permitted to copy and distribute verbatim copies
6 | of this license document, but changing it is not allowed.
7 |
8 |
9 | This version of the GNU Lesser General Public License incorporates
10 | the terms and conditions of version 3 of the GNU General Public
11 | License, supplemented by the additional permissions listed below.
12 |
13 | 0. Additional Definitions.
14 |
15 | As used herein, "this License" refers to version 3 of the GNU Lesser
16 | General Public License, and the "GNU GPL" refers to version 3 of the GNU
17 | General Public License.
18 |
19 | "The Library" refers to a covered work governed by this License,
20 | other than an Application or a Combined Work as defined below.
21 |
22 | An "Application" is any work that makes use of an interface provided
23 | by the Library, but which is not otherwise based on the Library.
24 | Defining a subclass of a class defined by the Library is deemed a mode
25 | of using an interface provided by the Library.
26 |
27 | A "Combined Work" is a work produced by combining or linking an
28 | Application with the Library. The particular version of the Library
29 | with which the Combined Work was made is also called the "Linked
30 | Version".
31 |
32 | The "Minimal Corresponding Source" for a Combined Work means the
33 | Corresponding Source for the Combined Work, excluding any source code
34 | for portions of the Combined Work that, considered in isolation, are
35 | based on the Application, and not on the Linked Version.
36 |
37 | The "Corresponding Application Code" for a Combined Work means the
38 | object code and/or source code for the Application, including any data
39 | and utility programs needed for reproducing the Combined Work from the
40 | Application, but excluding the System Libraries of the Combined Work.
41 |
42 | 1. Exception to Section 3 of the GNU GPL.
43 |
44 | You may convey a covered work under sections 3 and 4 of this License
45 | without being bound by section 3 of the GNU GPL.
46 |
47 | 2. Conveying Modified Versions.
48 |
49 | If you modify a copy of the Library, and, in your modifications, a
50 | facility refers to a function or data to be supplied by an Application
51 | that uses the facility (other than as an argument passed when the
52 | facility is invoked), then you may convey a copy of the modified
53 | version:
54 |
55 | a) under this License, provided that you make a good faith effort to
56 | ensure that, in the event an Application does not supply the
57 | function or data, the facility still operates, and performs
58 | whatever part of its purpose remains meaningful, or
59 |
60 | b) under the GNU GPL, with none of the additional permissions of
61 | this License applicable to that copy.
62 |
63 | 3. Object Code Incorporating Material from Library Header Files.
64 |
65 | The object code form of an Application may incorporate material from
66 | a header file that is part of the Library. You may convey such object
67 | code under terms of your choice, provided that, if the incorporated
68 | material is not limited to numerical parameters, data structure
69 | layouts and accessors, or small macros, inline functions and templates
70 | (ten or fewer lines in length), you do both of the following:
71 |
72 | a) Give prominent notice with each copy of the object code that the
73 | Library is used in it and that the Library and its use are
74 | covered by this License.
75 |
76 | b) Accompany the object code with a copy of the GNU GPL and this license
77 | document.
78 |
79 | 4. Combined Works.
80 |
81 | You may convey a Combined Work under terms of your choice that,
82 | taken together, effectively do not restrict modification of the
83 | portions of the Library contained in the Combined Work and reverse
84 | engineering for debugging such modifications, if you also do each of
85 | the following:
86 |
87 | a) Give prominent notice with each copy of the Combined Work that
88 | the Library is used in it and that the Library and its use are
89 | covered by this License.
90 |
91 | b) Accompany the Combined Work with a copy of the GNU GPL and this license
92 | document.
93 |
94 | c) For a Combined Work that displays copyright notices during
95 | execution, include the copyright notice for the Library among
96 | these notices, as well as a reference directing the user to the
97 | copies of the GNU GPL and this license document.
98 |
99 | d) Do one of the following:
100 |
101 | 0) Convey the Minimal Corresponding Source under the terms of this
102 | License, and the Corresponding Application Code in a form
103 | suitable for, and under terms that permit, the user to
104 | recombine or relink the Application with a modified version of
105 | the Linked Version to produce a modified Combined Work, in the
106 | manner specified by section 6 of the GNU GPL for conveying
107 | Corresponding Source.
108 |
109 | 1) Use a suitable shared library mechanism for linking with the
110 | Library. A suitable mechanism is one that (a) uses at run time
111 | a copy of the Library already present on the user's computer
112 | system, and (b) will operate properly with a modified version
113 | of the Library that is interface-compatible with the Linked
114 | Version.
115 |
116 | e) Provide Installation Information, but only if you would otherwise
117 | be required to provide such information under section 6 of the
118 | GNU GPL, and only to the extent that such information is
119 | necessary to install and execute a modified version of the
120 | Combined Work produced by recombining or relinking the
121 | Application with a modified version of the Linked Version. (If
122 | you use option 4d0, the Installation Information must accompany
123 | the Minimal Corresponding Source and Corresponding Application
124 | Code. If you use option 4d1, you must provide the Installation
125 | Information in the manner specified by section 6 of the GNU GPL
126 | for conveying Corresponding Source.)
127 |
128 | 5. Combined Libraries.
129 |
130 | You may place library facilities that are a work based on the
131 | Library side by side in a single library together with other library
132 | facilities that are not Applications and are not covered by this
133 | License, and convey such a combined library under terms of your
134 | choice, if you do both of the following:
135 |
136 | a) Accompany the combined library with a copy of the same work based
137 | on the Library, uncombined with any other library facilities,
138 | conveyed under the terms of this License.
139 |
140 | b) Give prominent notice with the combined library that part of it
141 | is a work based on the Library, and explaining where to find the
142 | accompanying uncombined form of the same work.
143 |
144 | 6. Revised Versions of the GNU Lesser General Public License.
145 |
146 | The Free Software Foundation may publish revised and/or new versions
147 | of the GNU Lesser General Public License from time to time. Such new
148 | versions will be similar in spirit to the present version, but may
149 | differ in detail to address new problems or concerns.
150 |
151 | Each version is given a distinguishing version number. If the
152 | Library as you received it specifies that a certain numbered version
153 | of the GNU Lesser General Public License "or any later version"
154 | applies to it, you have the option of following the terms and
155 | conditions either of that published version or of any later version
156 | published by the Free Software Foundation. If the Library as you
157 | received it does not specify a version number of the GNU Lesser
158 | General Public License, you may choose any version of the GNU Lesser
159 | General Public License ever published by the Free Software Foundation.
160 |
161 | If the Library as you received it specifies that a proxy can decide
162 | whether future versions of the GNU Lesser General Public License shall
163 | apply, that proxy's public statement of acceptance of any version is
164 | permanent authorization for you to choose that version for the
165 | Library.
166 |
--------------------------------------------------------------------------------
/test/DropboxManager.Tests.pas:
--------------------------------------------------------------------------------
1 | {
2 | Copyright (C) 2017 by Clever Components
3 |
4 | Author: Sergey Shirokov
5 |
6 | Website: www.CleverComponents.com
7 |
8 | This file is part of Dropbox Client Library for Delphi.
9 |
10 | Dropbox Client Library for Delphi is free software:
11 | you can redistribute it and/or modify it under the terms of
12 | the GNU Lesser General Public License version 3
13 | as published by the Free Software Foundation and appearing in the
14 | included file COPYING.LESSER.
15 |
16 | Dropbox Client Library for Delphi is distributed in the hope
17 | that it will be useful, but WITHOUT ANY WARRANTY; without even the
18 | implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
19 | See the GNU Lesser General Public License for more details.
20 |
21 | You should have received a copy of the GNU Lesser General Public License
22 | along with Dropbox Client Library. If not, see .
23 |
24 | The current version of Dropbox Client Client Library for Delphi needs for
25 | the non-free library Clever Internet Suite. This is a drawback,
26 | and we suggest the task of changing
27 | the program so that it does the same job without the non-free library.
28 | Anyone who thinks of doing substantial further work on the program,
29 | first may free it from dependence on the non-free library.
30 | }
31 |
32 | unit DropboxManager.Tests;
33 |
34 | interface
35 |
36 | uses
37 | System.Classes, System.SysUtils, TestFramework, DropboxManager, DropboxApi, DropboxApi.Persister, DropboxApi.Data;
38 |
39 | type
40 | TDropboxManagerTests = class(TTestCase)
41 | strict private
42 | procedure AssignCredentials(ADropbox: TDropboxManager);
43 | published
44 | procedure TestSerialization;
45 | procedure TestFolderRoutine;
46 | procedure TestFileRoutine;
47 | procedure TestCopyMove;
48 | procedure TestSaveUrl;
49 | end;
50 |
51 | implementation
52 |
53 | { TDropboxManagerTests }
54 |
55 | procedure TDropboxManagerTests.AssignCredentials(ADropbox: TDropboxManager);
56 | begin
57 | ADropbox.ClientID := 'x0hh3lne06oc1cg';
58 | ADropbox.ClientSecret := 'xrkh8yumfunrrnl';
59 | ADropbox.RedirectURL := 'http://localhost:55896';
60 | end;
61 |
62 | procedure TDropboxManagerTests.TestCopyMove;
63 | var
64 | dropbox: TDropboxManager;
65 | list: TStrings;
66 | begin
67 | dropbox := nil;
68 | list := nil;
69 | try
70 | dropbox := TDropboxManager.Create();
71 | list := TStringList.Create();
72 |
73 | AssignCredentials(dropbox);
74 |
75 | try
76 | dropbox.Delete('/TestFolder');
77 | except
78 | on EDropboxException do;
79 | end;
80 |
81 | try
82 | dropbox.Delete('/TestFolderCopy');
83 | except
84 | on EDropboxException do;
85 | end;
86 |
87 | try
88 | dropbox.Delete('/TestFolderMove');
89 | except
90 | on EDropboxException do;
91 | end;
92 |
93 | dropbox.CreateFolder('/TestFolder');
94 |
95 | dropbox.Copy('/TestFolder', '/TestFolderCopy');
96 |
97 | dropbox.Move('/TestFolderCopy', '/TestFolderMove');
98 |
99 | dropbox.Search('', 'TestFolderCopy', False, list);
100 | Assert(0 = list.Count);
101 |
102 | dropbox.Delete('/TestFolder');
103 | dropbox.Delete('/TestFolderMove');
104 | finally
105 | list.Free();
106 | dropbox.Free();
107 | end;
108 | end;
109 |
110 | procedure TDropboxManagerTests.TestFileRoutine;
111 | var
112 | dropbox: TDropboxManager;
113 | list: TStrings;
114 | stream: TStringStream;
115 | begin
116 | dropbox := nil;
117 | list := nil;
118 | stream := nil;
119 | try
120 | dropbox := TDropboxManager.Create();
121 | list := TStringList.Create();
122 |
123 | AssignCredentials(dropbox);
124 |
125 | stream := TStringStream.Create('test content', TEncoding.UTF8);
126 |
127 | try
128 | dropbox.Delete('/testfile.txt');
129 | except
130 | on EDropboxException do;
131 | end;
132 |
133 | dropbox.Upload(stream, '/testfile.txt');
134 |
135 | stream.Size := 0;
136 |
137 | dropbox.Download('/testfile.txt', stream);
138 |
139 | Assert('test content' = stream.DataString);
140 |
141 | dropbox.Search('', 'testfile', False, list);
142 |
143 | Assert(1 = list.Count);
144 | Assert('/testfile.txt' = list[0]);
145 |
146 | dropbox.Delete('/testfile.txt');
147 |
148 | Sleep(2000);
149 |
150 | dropbox.Search('', 'testfile', False, list);
151 | Assert(0 = list.Count);
152 |
153 | dropbox.Search('', 'testfile', True, list);
154 | Assert(1 = list.Count);
155 | Assert(' /testfile.txt' = list[0]);
156 | finally
157 | stream.Free();
158 | list.Free();
159 | dropbox.Free();
160 | end;
161 | end;
162 |
163 | procedure TDropboxManagerTests.TestFolderRoutine;
164 | var
165 | dropbox: TDropboxManager;
166 | list: TStrings;
167 | cnt: Integer;
168 | begin
169 | dropbox := nil;
170 | list := nil;
171 | try
172 | dropbox := TDropboxManager.Create();
173 | list := TStringList.Create();
174 |
175 | AssignCredentials(dropbox);
176 |
177 | try
178 | dropbox.Delete('/TestFolder');
179 | except
180 | on EDropboxException do;
181 | end;
182 |
183 | dropbox.ListFolder('', list);
184 | cnt := list.Count;
185 |
186 | dropbox.CreateFolder('/TestFolder');
187 |
188 | dropbox.ListFolder('', list);
189 | Assert(cnt + 1 = list.Count);
190 |
191 | dropbox.Delete('/TestFolder');
192 | finally
193 | list.Free();
194 | dropbox.Free();
195 | end;
196 | end;
197 |
198 | procedure TDropboxManagerTests.TestSaveUrl;
199 | var
200 | dropbox: TDropboxManager;
201 | list: TStrings;
202 | cnt: Integer;
203 | id: string;
204 | status: TSaveUrlStatus;
205 | begin
206 | dropbox := nil;
207 | list := nil;
208 | try
209 | dropbox := TDropboxManager.Create();
210 | list := TStringList.Create();
211 |
212 | AssignCredentials(dropbox);
213 |
214 | try
215 | dropbox.Delete('/testfile.txt');
216 | except
217 | on EDropboxException do;
218 | end;
219 |
220 | dropbox.ListFolder('', list);
221 | cnt := list.Count;
222 |
223 | id := dropbox.SaveUrl('/testfile.txt', 'http://www.clevercomponents.com/robots.txt');
224 |
225 | Assert('' <> id);
226 |
227 | repeat
228 | status := dropbox.SaveUrlCheckStatus(id);
229 | until (status <> usInProgress);
230 |
231 | Assert(usComplete = status);
232 |
233 | dropbox.ListFolder('', list);
234 | Assert(cnt + 1 = list.Count);
235 |
236 | dropbox.Delete('/testfile.txt');
237 | finally
238 | list.Free();
239 | dropbox.Free();
240 | end;
241 | end;
242 |
243 | procedure TDropboxManagerTests.TestSerialization;
244 | const
245 | source = '{"entries": ['
246 | + '{".tag": "file", "name": "Get Started with Dropbox.pdf", "path_lower": "/get started with dropbox.pdf",'
247 | + ' "path_display": "/Get Started with Dropbox.pdf", "id": "id:99W9FmuZVTAAAAAAAAAAAg", "client_modified": "2016-12-20T21:27:34Z",'
248 | + ' "server_modified": "2016-12-20T21:28:34Z", "rev": "1521e41da", "size": 905827}],'
249 | + ' "cursor": "AAHiavvxdBrJsoC9q5E4girQd5LvgbyGhnTR1lYC5mo7OU_Ni0h_thdoLdQocqOK03ZyRPyshA2ifDnjIeyWV_FZ6UwMsh6unZMhoVpDPkCrXp8jYtnGUJ-g9u8LKjhatGA3e9ZAULV4IeFaUOMpLcjD", "has_more": false}';
250 |
251 | var
252 | json: TDropboxJsonSerializer;
253 | obj: TListFolderResult;
254 | fileEntry: TFileMetadata;
255 | begin
256 | json := nil;
257 | obj := nil;
258 | try
259 | json := TDropboxJsonSerializer.Create();
260 | obj := json.JsonToObject(TListFolderResult, source) as TListFolderResult;
261 |
262 | Assert(1 = Length(obj.Entries));
263 | Assert('AAHiavvxdBrJsoC9q5E4girQd5LvgbyGhnTR1lYC5mo7OU_Ni0h_thdoLdQocqOK03ZyRPyshA2ifDnjIeyWV_FZ6UwMsh6unZMhoVpDPkCrXp8jYtnGUJ-g9u8LKjhatGA3e9ZAULV4IeFaUOMpLcjD' = obj.Cursor);
264 | Assert(not obj.HasMore);
265 |
266 | fileEntry := obj.Entries[0] as TFileMetadata;
267 |
268 | Assert('Get Started with Dropbox.pdf' = fileEntry.Name);
269 | Assert('/get started with dropbox.pdf' = fileEntry.PathLower);
270 | Assert('/Get Started with Dropbox.pdf' = fileEntry.PathDisplay);
271 | Assert('id:99W9FmuZVTAAAAAAAAAAAg' = fileEntry.Id);
272 | Assert('2016-12-20T21:27:34Z' = fileEntry.ClientModified);
273 | Assert('2016-12-20T21:28:34Z' = fileEntry.ServerModified);
274 | Assert('1521e41da' = fileEntry.Rev);
275 | Assert(905827 = fileEntry.Size);
276 | finally
277 | obj.Free();
278 | json.Free();
279 | end;
280 | end;
281 |
282 | initialization
283 | TestFramework.RegisterTest(TDropboxManagerTests.Suite);
284 |
285 | end.
286 |
--------------------------------------------------------------------------------
/src/DropboxApi.Routes.pas:
--------------------------------------------------------------------------------
1 | {
2 | Copyright (C) 2017 by Clever Components
3 |
4 | Author: Sergey Shirokov
5 |
6 | Website: www.CleverComponents.com
7 |
8 | This file is part of Dropbox Client Library for Delphi.
9 |
10 | Dropbox Client Library for Delphi is free software:
11 | you can redistribute it and/or modify it under the terms of
12 | the GNU Lesser General Public License version 3
13 | as published by the Free Software Foundation and appearing in the
14 | included file COPYING.LESSER.
15 |
16 | Dropbox Client Library for Delphi is distributed in the hope
17 | that it will be useful, but WITHOUT ANY WARRANTY; without even the
18 | implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
19 | See the GNU Lesser General Public License for more details.
20 |
21 | You should have received a copy of the GNU Lesser General Public License
22 | along with Dropbox Client Library. If not, see .
23 |
24 | The current version of Dropbox Client Client Library for Delphi needs for
25 | the non-free library Clever Internet Suite. This is a drawback,
26 | and we suggest the task of changing
27 | the program so that it does the same job without the non-free library.
28 | Anyone who thinks of doing substantial further work on the program,
29 | first may free it from dependence on the non-free library.
30 | }
31 |
32 | unit DropboxApi.Routes;
33 |
34 | interface
35 |
36 | uses
37 | System.Classes, System.SysUtils, DropboxApi, DropboxApi.Data, DropboxApi.Requests;
38 |
39 | type
40 | TDropboxRoutes = class
41 | strict private
42 | FService: TService;
43 | public
44 | constructor Create(AService: TService);
45 |
46 | property Service: TService read FService;
47 | end;
48 |
49 | TAuthUserRoutes = class(TDropboxRoutes)
50 | public
51 | procedure TokenRevoke;
52 | end;
53 |
54 | TFilesUserRoutes = class(TDropboxRoutes)
55 | function Copy(ARelocationArg: TRelocationArg): TMetadata;
56 | //copy_batch
57 | //copy_batch/check
58 | //copy_reference/get
59 | //copy_reference/save
60 | function CreateFolder(ACreateFolderArg: TCreateFolderArg): TFolderMetadata;
61 | function Delete(ADeleteArg: TDeleteArg): TMetadata;
62 | //delete_batch
63 | //delete_batch/check
64 | function Download(ADownloadArg: TDownloadArg; ABody: TStream): TFileMetadata;
65 | //get_metadata
66 | //get_preview
67 | //get_temporary_link
68 | //get_thumbnail
69 | function ListFolder(AListFolderArg: TListFolderArg): TListFolderResult;
70 | function ListFolderContinue(AListFolderContinueArg: TListFolderContinueArg): TListFolderResult;
71 | //list_folder/get_latest_cursor
72 | //list_folder/longpoll
73 | //list_revisions
74 | function Move(ARelocationArg: TRelocationArg): TMetadata;
75 | //move_batch
76 | //move_batch/check
77 | //permanently_delete
78 | //restore
79 | function SaveUrl(ASaveUrlArg: TSaveUrlArg): TSaveUrlResult;
80 | function SaveUrlCheckJobStatus(APollArg: TPollArg): TSaveUrlJobStatus;
81 | function Search(ASearchArg: TSearchArg): TSearchResult;
82 | function Upload(ACommitInfo: TCommitInfo; ABody: TStream): TFileMetadata;
83 | //upload_session/append_v2
84 | //upload_session/finish
85 | //upload_session/finish_batch
86 | //upload_session/finish_batch/check
87 | //upload_session/start
88 | end;
89 |
90 | TDropboxClient = class(TService)
91 | strict private
92 | FAuth: TAuthUserRoutes;
93 | FFiles: TFilesUserRoutes;
94 |
95 | function GetAuth: TAuthUserRoutes;
96 | function GetFiles: TFilesUserRoutes;
97 | strict protected
98 | function CreateAuth: TAuthUserRoutes; virtual;
99 | function CreateFiles: TFilesUserRoutes; virtual;
100 | public
101 | constructor Create(AInitializer: TServiceInitializer);
102 | destructor Destroy; override;
103 |
104 | property Auth: TAuthUserRoutes read GetAuth;
105 | property Files: TFilesUserRoutes read GetFiles;
106 | //PaperUserRoutes Paper
107 | //SharingUserRoutes Sharing
108 | //UsersUserRoutes Users
109 | end;
110 |
111 | implementation
112 |
113 | { TDropboxClient }
114 |
115 | constructor TDropboxClient.Create(AInitializer: TServiceInitializer);
116 | begin
117 | inherited Create(AInitializer);
118 |
119 | FAuth := nil;
120 | FFiles := nil;
121 | end;
122 |
123 | function TDropboxClient.CreateAuth: TAuthUserRoutes;
124 | begin
125 | Result := TAuthUserRoutes.Create(Self);
126 | end;
127 |
128 | function TDropboxClient.CreateFiles: TFilesUserRoutes;
129 | begin
130 | Result := TFilesUserRoutes.Create(Self);
131 | end;
132 |
133 | destructor TDropboxClient.Destroy;
134 | begin
135 | FreeAndNil(FAuth);
136 | FreeAndNil(FFiles);
137 |
138 | inherited Destroy();
139 | end;
140 |
141 | function TDropboxClient.GetAuth: TAuthUserRoutes;
142 | begin
143 | if (FAuth = nil) then
144 | begin
145 | FAuth := CreateAuth();
146 | end;
147 | Result := FAuth;
148 | end;
149 |
150 | function TDropboxClient.GetFiles: TFilesUserRoutes;
151 | begin
152 | if (FFiles = nil) then
153 | begin
154 | FFiles := CreateFiles();
155 | end;
156 | Result := FFiles;
157 | end;
158 |
159 | { TDropboxRoutes }
160 |
161 | constructor TDropboxRoutes.Create(AService: TService);
162 | begin
163 | inherited Create();
164 | FService := AService;
165 | end;
166 |
167 | { TAuthUserRoutes }
168 |
169 | procedure TAuthUserRoutes.TokenRevoke;
170 | begin
171 | Service.Initializer.Credential.RevokeAuthorization();
172 | end;
173 |
174 | { TFilesUserRoutes }
175 |
176 | function TFilesUserRoutes.Copy(ARelocationArg: TRelocationArg): TMetadata;
177 | var
178 | request: TFilesCopyRequest;
179 | begin
180 | request := TFilesCopyRequest.Create(Service, ARelocationArg);
181 | try
182 | Result := request.Execute();
183 | finally
184 | request.Free();
185 | end;
186 | end;
187 |
188 | function TFilesUserRoutes.CreateFolder(ACreateFolderArg: TCreateFolderArg): TFolderMetadata;
189 | var
190 | request: TFilesCreateFolderRequest;
191 | begin
192 | request := TFilesCreateFolderRequest.Create(Service, ACreateFolderArg);
193 | try
194 | Result := request.Execute();
195 | finally
196 | request.Free();
197 | end;
198 | end;
199 |
200 | function TFilesUserRoutes.Delete(ADeleteArg: TDeleteArg): TMetadata;
201 | var
202 | request: TFilesDeleteRequest;
203 | begin
204 | request := TFilesDeleteRequest.Create(Service, ADeleteArg);
205 | try
206 | Result := request.Execute();
207 | finally
208 | request.Free();
209 | end;
210 | end;
211 |
212 | function TFilesUserRoutes.Download(ADownloadArg: TDownloadArg; ABody: TStream): TFileMetadata;
213 | var
214 | request: TFilesDownloadRequest;
215 | begin
216 | request := TFilesDownloadRequest.Create(Service, ADownloadArg, ABody);
217 | try
218 | Result := request.Execute();
219 | finally
220 | request.Free();
221 | end;
222 | end;
223 |
224 | function TFilesUserRoutes.ListFolder(AListFolderArg: TListFolderArg): TListFolderResult;
225 | var
226 | request: TFilesListFolderRequest;
227 | begin
228 | request := TFilesListFolderRequest.Create(Service, AListFolderArg);
229 | try
230 | Result := request.Execute();
231 | finally
232 | request.Free();
233 | end;
234 | end;
235 |
236 | function TFilesUserRoutes.ListFolderContinue(AListFolderContinueArg: TListFolderContinueArg): TListFolderResult;
237 | var
238 | request: TFilesListFolderContinueRequest;
239 | begin
240 | request := TFilesListFolderContinueRequest.Create(Service, AListFolderContinueArg);
241 | try
242 | Result := request.Execute();
243 | finally
244 | request.Free();
245 | end;
246 | end;
247 |
248 | function TFilesUserRoutes.Move(ARelocationArg: TRelocationArg): TMetadata;
249 | var
250 | request: TFilesMoveRequest;
251 | begin
252 | request := TFilesMoveRequest.Create(Service, ARelocationArg);
253 | try
254 | Result := request.Execute();
255 | finally
256 | request.Free();
257 | end;
258 | end;
259 |
260 | function TFilesUserRoutes.SaveUrl(ASaveUrlArg: TSaveUrlArg): TSaveUrlResult;
261 | var
262 | request: TFilesSaveUrlRequest;
263 | begin
264 | request := TFilesSaveUrlRequest.Create(Service, ASaveUrlArg);
265 | try
266 | Result := request.Execute();
267 | finally
268 | request.Free();
269 | end;
270 | end;
271 |
272 | function TFilesUserRoutes.SaveUrlCheckJobStatus(APollArg: TPollArg): TSaveUrlJobStatus;
273 | var
274 | request: TFilesSaveUrlCheckJobStatusRequest;
275 | begin
276 | request := TFilesSaveUrlCheckJobStatusRequest.Create(Service, APollArg);
277 | try
278 | Result := request.Execute();
279 | finally
280 | request.Free();
281 | end;
282 | end;
283 |
284 | function TFilesUserRoutes.Search(ASearchArg: TSearchArg): TSearchResult;
285 | var
286 | request: TFilesSearchRequest;
287 | begin
288 | request := TFilesSearchRequest.Create(Service, ASearchArg);
289 | try
290 | Result := request.Execute();
291 | finally
292 | request.Free();
293 | end;
294 | end;
295 |
296 | function TFilesUserRoutes.Upload(ACommitInfo: TCommitInfo; ABody: TStream): TFileMetadata;
297 | var
298 | request: TFilesUploadRequest;
299 | begin
300 | request := TFilesUploadRequest.Create(Service, ACommitInfo, ABody);
301 | try
302 | Result := request.Execute();
303 | finally
304 | request.Free();
305 | end;
306 | end;
307 |
308 | end.
309 |
--------------------------------------------------------------------------------
/test/Test.dproj:
--------------------------------------------------------------------------------
1 |
2 |
3 | {77B61FFE-DE2E-4DBE-BE40-D39F6E982870}
4 | 14.4
5 | VCL
6 | Test.dpr
7 | True
8 | Debug
9 | Win32
10 | 3
11 | Application
12 |
13 |
14 | true
15 |
16 |
17 | true
18 | Base
19 | true
20 |
21 |
22 | true
23 | Base
24 | true
25 |
26 |
27 | true
28 | Base
29 | true
30 |
31 |
32 | true
33 | Cfg_1
34 | true
35 | true
36 |
37 |
38 | true
39 | Base
40 | true
41 |
42 |
43 | $(BDS)\bin\delphi_PROJECTICON.ico
44 | System;Xml;Data;Datasnap;Web;Soap;Vcl;Vcl.Imaging;Vcl.Touch;Vcl.Samples;Vcl.Shell;$(DCC_Namespace)
45 | .\$(Platform)\$(Config)
46 | .\$(Platform)\$(Config)
47 | false
48 | false
49 | false
50 | false
51 | false
52 |
53 |
54 | 1033
55 | true
56 | bindcompfmx;DBXSqliteDriver;vcldbx;fmx;rtl;dbrtl;DbxClientDriver;IndySystem;bindcomp;inetdb;vclib;inetdbbde;DBXInterBaseDriver;DataSnapCommon;xmlrtl;svnui;ibxpress;DbxCommonDriver;vclimg;IndyProtocols;dbxcds;DBXMySQLDriver;MetropolisUILiveTile;vclactnband;bindengine;vcldb;soaprtl;bindcompdbx;vcldsnap;bindcompvcl;vclie;vcltouch;websnap;CustomIPTransport;VclSmp;dsnap;IndyIPServer;fmxase;vcl;IndyCore;clinetsuitedXE3;IndyIPCommon;CloudService;dsnapcon;inet;fmxobj;vclx;clinetsuiteSSHdXE3;inetdbxpress;webdsnap;svn;fmxdae;bdertl;dbexpress;adortl;IndyIPClient;$(DCC_UsePackage)
57 | Winapi;System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;Bde;$(DCC_Namespace)
58 | $(BDS)\bin\default_app.manifest
59 | CompanyName=;FileDescription=;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=;ProductVersion=1.0.0.0;Comments=
60 |
61 |
62 | Winapi;System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;$(DCC_Namespace)
63 | $(BDS)\bin\default_app.manifest
64 | true
65 | 1033
66 | CompanyName=;FileDescription=;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=;ProductVersion=1.0.0.0;Comments=
67 | bindcompfmx;DBXSqliteDriver;fmx;rtl;dbrtl;DbxClientDriver;IndySystem;bindcomp;inetdb;DBXInterBaseDriver;DataSnapCommon;xmlrtl;DbxCommonDriver;vclimg;IndyProtocols;dbxcds;DBXMySQLDriver;vclactnband;bindengine;vcldb;soaprtl;bindcompdbx;vcldsnap;bindcompvcl;vclie;vcltouch;websnap;CustomIPTransport;VclSmp;dsnap;IndyIPServer;fmxase;vcl;IndyCore;IndyIPCommon;dsnapcon;inet;fmxobj;vclx;inetdbxpress;webdsnap;fmxdae;dbexpress;IndyIPClient;$(DCC_UsePackage)
68 |
69 |
70 | DEBUG;$(DCC_Define)
71 | true
72 | false
73 | true
74 | true
75 | true
76 |
77 |
78 | 1033
79 | false
80 | true
81 | false
82 |
83 |
84 | false
85 | RELEASE;$(DCC_Define)
86 | 0
87 | false
88 |
89 |
90 |
91 | MainSource
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 | Cfg_2
105 | Base
106 |
107 |
108 | Base
109 |
110 |
111 | Cfg_1
112 | Base
113 |
114 |
115 |
116 | Delphi.Personality.12
117 |
118 |
119 |
120 |
121 | False
122 | False
123 | 1
124 | 0
125 | 0
126 | 0
127 | False
128 | False
129 | False
130 | False
131 | False
132 | 1049
133 | 1251
134 |
135 |
136 |
137 |
138 | 1.0.0.0
139 |
140 |
141 |
142 |
143 |
144 | 1.0.0.0
145 |
146 |
147 |
148 |
149 |
150 |
151 |
152 |
153 |
154 |
155 |
156 | Test.dpr
157 |
158 |
159 |
160 |
161 | True
162 | True
163 |
164 |
165 | 12
166 |
167 |
168 |
169 |
170 |
--------------------------------------------------------------------------------
/src/DropboxApi.Persister.pas:
--------------------------------------------------------------------------------
1 | {
2 | Copyright (C) 2017 by Clever Components
3 |
4 | Author: Sergey Shirokov
5 |
6 | Website: www.CleverComponents.com
7 |
8 | This file is part of Dropbox Client Library for Delphi.
9 |
10 | Dropbox Client Library for Delphi is free software:
11 | you can redistribute it and/or modify it under the terms of
12 | the GNU Lesser General Public License version 3
13 | as published by the Free Software Foundation and appearing in the
14 | included file COPYING.LESSER.
15 |
16 | Dropbox Client Library for Delphi is distributed in the hope
17 | that it will be useful, but WITHOUT ANY WARRANTY; without even the
18 | implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
19 | See the GNU Lesser General Public License for more details.
20 |
21 | You should have received a copy of the GNU Lesser General Public License
22 | along with Dropbox Client Library. If not, see .
23 |
24 | The current version of Dropbox Client Client Library for Delphi needs for
25 | the non-free library Clever Internet Suite. This is a drawback,
26 | and we suggest the task of changing
27 | the program so that it does the same job without the non-free library.
28 | Anyone who thinks of doing substantial further work on the program,
29 | first may free it from dependence on the non-free library.
30 | }
31 |
32 | unit DropboxApi.Persister;
33 |
34 | interface
35 |
36 | uses
37 | System.Classes, System.SysUtils, DropboxApi, clOAuth, clUriUtils, clHttp, clHttpRequest, clHeaderFieldList,
38 | clJsonSerializer;
39 |
40 | type
41 | TDropboxOAuthCredential = class(TCredential)
42 | strict private
43 | FClientID: string;
44 | FClientSecret: string;
45 | FRedirectURL: string;
46 | FOAuth: TclOAuth;
47 | public
48 | constructor Create;
49 | destructor Destroy; override;
50 |
51 | function GetAuthorization: string; override;
52 | function RefreshAuthorization: string; override;
53 | procedure RevokeAuthorization; override;
54 | procedure Abort; override;
55 |
56 | property ClientID: string read FClientID write FClientID;
57 | property ClientSecret: string read FClientSecret write FClientSecret;
58 | property RedirectURL: string read FRedirectURL write FRedirectURL;
59 | end;
60 |
61 | TDropboxHttpClient = class(THttpClient)
62 | strict private
63 | FHttp: TclHttp;
64 |
65 | procedure CheckResponse(const AJsonResponse: string);
66 | protected
67 | function GetStatusCode: Integer; override;
68 | public
69 | constructor Create(AInitializer: TServiceInitializer);
70 | destructor Destroy; override;
71 |
72 | function RpcEndPointRequest(const AUri: string; const ARequest: string): string; override;
73 | function ContentUploadEndPointRequest(const AUri: string; const ARequestHeader: string; ABody: TStream): string; override;
74 | function ContentDownloadEndPointRequest(const AUri: string; const ARequestHeader: string; ABody: TStream): string; override;
75 | procedure Abort; override;
76 | end;
77 |
78 | TDropboxJsonSerializer = class(TJsonSerializer)
79 | strict private
80 | FSerializer: clJsonSerializer.TclJsonSerializer;
81 | public
82 | constructor Create;
83 | destructor Destroy; override;
84 |
85 | function JsonToException(const AJson: string): EDropboxException; override;
86 | function ExceptionToJson(E: EDropboxException): string; override;
87 |
88 | function JsonToObject(AType: TClass; const AJson: string): TObject; override;
89 | function ObjectToJson(AObject: TObject): string; override;
90 | end;
91 |
92 | TDropboxServiceInitializer = class(TServiceInitializer)
93 | strict private
94 | FHttpClient: THttpClient;
95 | FJsonSerializer: TJsonSerializer;
96 | strict protected
97 | function GetHttpClient: THttpClient; override;
98 | function GetJsonSerializer: TJsonSerializer; override;
99 | public
100 | constructor Create(ACredential: TCredential; const ApplicationName: string);
101 | destructor Destroy; override;
102 | end;
103 |
104 | implementation
105 |
106 | { TDropboxOAuthCredential }
107 |
108 | procedure TDropboxOAuthCredential.Abort;
109 | begin
110 | FOAuth.Close();
111 | end;
112 |
113 | constructor TDropboxOAuthCredential.Create;
114 | begin
115 | inherited Create();
116 | FOAuth := TclOAuth.Create(nil);
117 | end;
118 |
119 | destructor TDropboxOAuthCredential.Destroy;
120 | begin
121 | FOAuth.Free();
122 | inherited Destroy();
123 | end;
124 |
125 | function TDropboxOAuthCredential.GetAuthorization: string;
126 | var
127 | uri: TclUrlParser;
128 | begin
129 | FOAuth.AuthURL := 'https://www.dropbox.com/oauth2/authorize';
130 | FOAuth.TokenURL := 'https://api.dropbox.com/oauth2/token';
131 |
132 | FOAuth.ClientID := ClientID;
133 | FOAuth.ClientSecret := ClientSecret;
134 | FOAuth.RedirectURL := RedirectURL;
135 |
136 | uri := TclUrlParser.Create();
137 | try
138 | uri.Parse(FOAuth.RedirectURL);
139 | FOAuth.LocalWebServerPort := uri.Port;
140 | finally
141 | uri.Free();
142 | end;
143 |
144 | Result := FOAuth.GetAuthorization();
145 | end;
146 |
147 | function TDropboxOAuthCredential.RefreshAuthorization: string;
148 | begin
149 | Result := FOAuth.RefreshAuthorization();
150 | end;
151 |
152 | procedure TDropboxOAuthCredential.RevokeAuthorization;
153 | begin
154 | FOAuth.Close();
155 | end;
156 |
157 | { TDropboxHttpClient }
158 |
159 | procedure TDropboxHttpClient.Abort;
160 | begin
161 | FHttp.Close();
162 | end;
163 |
164 | procedure TDropboxHttpClient.CheckResponse(const AJsonResponse: string);
165 | begin
166 | if (FHttp.StatusCode >= 300) then
167 | begin
168 | if (FHttp.ResponseHeader.ContentType.ToLower().IndexOf('json') > -1) then
169 | begin
170 | raise Initializer.JsonSerializer.JsonToException(AJsonResponse);
171 | end else
172 | begin
173 | raise EclHttpError.Create(FHttp.StatusText, FHttp.StatusCode, AJsonResponse);
174 | end;
175 | end;
176 | end;
177 |
178 | constructor TDropboxHttpClient.Create(AInitializer: TServiceInitializer);
179 | begin
180 | inherited Create(AInitializer);
181 |
182 | FHttp := TclHttp.Create(nil);
183 | FHttp.UserAgent := Initializer.ApplicationName;
184 | FHttp.SilentHTTP := True;
185 | end;
186 |
187 | destructor TDropboxHttpClient.Destroy;
188 | begin
189 | FHttp.Free();
190 | inherited Destroy();
191 | end;
192 |
193 | function TDropboxHttpClient.GetStatusCode: Integer;
194 | begin
195 | Result := FHttp.StatusCode;
196 | end;
197 |
198 | function TDropboxHttpClient.RpcEndPointRequest(const AUri, ARequest: string): string;
199 | var
200 | req: TclHttpRequest;
201 | resp: TStringStream;
202 | begin
203 | req := nil;
204 | resp := nil;
205 | try
206 | req := TclHttpRequest.Create(nil);
207 |
208 | if (ARequest <> '') then
209 | begin
210 | req.BuildJSONRequest(ARequest);
211 | end;
212 |
213 | resp := TStringStream.Create('', TEncoding.UTF8);
214 |
215 | FHttp.Authorization := Initializer.Credential.GetAuthorization();
216 |
217 | FHttp.Post(AUri, req, resp);
218 |
219 | CheckResponse(resp.DataString);
220 |
221 | Result := resp.DataString;
222 | finally
223 | resp.Free();
224 | req.Free();
225 | end;
226 | end;
227 |
228 | function TDropboxHttpClient.ContentDownloadEndPointRequest(const AUri, ARequestHeader: string; ABody: TStream): string;
229 | var
230 | req: TclHttpRequest;
231 | fieldList: TclHeaderFieldList;
232 | begin
233 | req := nil;
234 | fieldList := nil;
235 | try
236 | req := TclHttpRequest.Create(nil);
237 |
238 | req.Header.ExtraFields.Add('Dropbox-API-Arg: ' + ARequestHeader);
239 |
240 | FHttp.Authorization := Initializer.Credential.GetAuthorization();
241 |
242 | FHttp.SendRequest('POST', AUri, req.HeaderSource, nil, nil, ABody);
243 |
244 | fieldList := TclHeaderFieldList.Create();
245 |
246 | fieldList.Parse(0, FHttp.ResponseHeader.ExtraFields);
247 |
248 | Result := fieldList.GetFieldValue('Dropbox-API-Result');
249 |
250 | CheckResponse(Result);
251 | finally
252 | fieldList.Free();
253 | req.Free();
254 | end;
255 | end;
256 |
257 | function TDropboxHttpClient.ContentUploadEndPointRequest(const AUri, ARequestHeader: string; ABody: TStream): string;
258 | var
259 | req: TclHttpRequest;
260 | resp: TStringStream;
261 | begin
262 | req := nil;
263 | resp := nil;
264 | try
265 | req := TclHttpRequest.Create(nil);
266 |
267 | req.Header.ContentType := 'application/octet-stream';
268 | req.Header.ExtraFields.Add('Dropbox-API-Arg: ' + ARequestHeader);
269 |
270 | resp := TStringStream.Create('', TEncoding.UTF8);
271 |
272 | FHttp.Authorization := Initializer.Credential.GetAuthorization();
273 |
274 | FHttp.SendRequest('POST', AUri, req.HeaderSource, ABody, nil, resp);
275 |
276 | CheckResponse(resp.DataString);
277 |
278 | Result := resp.DataString;
279 | finally
280 | resp.Free();
281 | req.Free();
282 | end;
283 | end;
284 |
285 | { TDropboxJsonSerializer }
286 |
287 | constructor TDropboxJsonSerializer.Create;
288 | begin
289 | inherited Create();
290 | FSerializer := clJsonSerializer.TclJsonSerializer.Create();
291 | end;
292 |
293 | destructor TDropboxJsonSerializer.Destroy;
294 | begin
295 | FSerializer.Free();
296 | inherited Destroy();
297 | end;
298 |
299 | function TDropboxJsonSerializer.ExceptionToJson(E: EDropboxException): string;
300 | begin
301 | Result := FSerializer.ObjectToJson(E);
302 | end;
303 |
304 | function TDropboxJsonSerializer.JsonToException(const AJson: string): EDropboxException;
305 | begin
306 | Result := EDropboxException.Create();
307 | try
308 | Result := FSerializer.JsonToObject(Result, AJson) as EDropboxException;
309 | except
310 | Result.Free();
311 | raise;
312 | end;
313 | end;
314 |
315 | function TDropboxJsonSerializer.JsonToObject(AType: TClass; const AJson: string): TObject;
316 | begin
317 | Result := FSerializer.JsonToObject(AType, AJson);
318 | end;
319 |
320 | function TDropboxJsonSerializer.ObjectToJson(AObject: TObject): string;
321 | begin
322 | Result := FSerializer.ObjectToJson(AObject);
323 | end;
324 |
325 | { TDropboxServiceInitializer }
326 |
327 | constructor TDropboxServiceInitializer.Create(ACredential: TCredential; const ApplicationName: string);
328 | begin
329 | inherited Create(ACredential, ApplicationName);
330 |
331 | FHttpClient := nil;
332 | FJsonSerializer := nil;
333 | end;
334 |
335 | destructor TDropboxServiceInitializer.Destroy;
336 | begin
337 | FHttpClient.Free();
338 | FJsonSerializer.Free();
339 |
340 | inherited Destroy();
341 | end;
342 |
343 | function TDropboxServiceInitializer.GetHttpClient: THttpClient;
344 | begin
345 | if (FHttpClient = nil) then
346 | begin
347 | FHttpClient := TDropboxHttpClient.Create(Self);
348 | end;
349 | Result := FHttpClient;
350 | end;
351 |
352 | function TDropboxServiceInitializer.GetJsonSerializer: TJsonSerializer;
353 | begin
354 | if (FJsonSerializer = nil) then
355 | begin
356 | FJsonSerializer := TDropboxJsonSerializer.Create();
357 | end;
358 | Result := FJsonSerializer;
359 | end;
360 |
361 | end.
362 |
--------------------------------------------------------------------------------
/src/DropboxManager.pas:
--------------------------------------------------------------------------------
1 | {
2 | Copyright (C) 2017 by Clever Components
3 |
4 | Author: Sergey Shirokov
5 |
6 | Website: www.CleverComponents.com
7 |
8 | This file is part of Dropbox Client Library for Delphi.
9 |
10 | Dropbox Client Library for Delphi is free software:
11 | you can redistribute it and/or modify it under the terms of
12 | the GNU Lesser General Public License version 3
13 | as published by the Free Software Foundation and appearing in the
14 | included file COPYING.LESSER.
15 |
16 | Dropbox Client Library for Delphi is distributed in the hope
17 | that it will be useful, but WITHOUT ANY WARRANTY; without even the
18 | implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
19 | See the GNU Lesser General Public License for more details.
20 |
21 | You should have received a copy of the GNU Lesser General Public License
22 | along with Dropbox Client Library. If not, see .
23 |
24 | The current version of Dropbox Client Client Library for Delphi needs for
25 | the non-free library Clever Internet Suite. This is a drawback,
26 | and we suggest the task of changing
27 | the program so that it does the same job without the non-free library.
28 | Anyone who thinks of doing substantial further work on the program,
29 | first may free it from dependence on the non-free library.
30 | }
31 |
32 | unit DropboxManager;
33 |
34 | interface
35 |
36 | uses
37 | System.Classes, System.SysUtils, DropboxApi, DropboxApi.Data, DropboxApi.Routes, DropboxApi.Persister;
38 |
39 | type
40 | TSaveUrlStatus = (usInProgress, usComplete, usFailed);
41 |
42 | TDropboxManager = class
43 | strict private
44 | FClientID: string;
45 | FClientSecret: string;
46 | FRedirectURL: string;
47 | FClient: TDropboxClient;
48 |
49 | function GetClient: TDropboxClient;
50 | procedure CollectFolderList(AListFolderResult: TListFolderResult; AList: TStrings);
51 | procedure CollectSearchList(ASearchResult: TSearchResult; AList: TStrings);
52 | public
53 | constructor Create;
54 | destructor Destroy; override;
55 |
56 | procedure CreateFolder(const APath: string);
57 | procedure ListFolder(const APath: string; AList: TStrings);
58 | procedure Delete(const APath: string);
59 | procedure Search(const APath, AQuery: string; ASearchDeleted: Boolean; AList: TStrings);
60 |
61 | procedure Copy(const AFromPath, AToPath: string);
62 | procedure Move(const AFromPath, AToPath: string);
63 |
64 | procedure Download(const ASourceFile: string; ADestination: TStream);
65 | procedure Upload(ASource: TStream; const ADestinationFile: string);
66 | function SaveUrl(const APath, AUrl: string): string;
67 | function SaveUrlCheckStatus(const AsyncJobId: string): TSaveUrlStatus;
68 |
69 | procedure Close;
70 |
71 | property ClientID: string read FClientID write FClientID;
72 | property ClientSecret: string read FClientSecret write FClientSecret;
73 | property RedirectURL: string read FRedirectURL write FRedirectURL;
74 | end;
75 |
76 | implementation
77 |
78 | { TDropboxManager }
79 |
80 | function TDropboxManager.SaveUrlCheckStatus(const AsyncJobId: string): TSaveUrlStatus;
81 | var
82 | args: TPollArg;
83 | res: TSaveUrlJobStatus;
84 | begin
85 | args := nil;
86 | res := nil;
87 | try
88 | args := TPollArg.Create();
89 | args.AsyncJobId := AsyncJobId;
90 |
91 | res := GetClient().Files.SaveUrlCheckJobStatus(args);
92 |
93 | if (res is TSaveUrlJobStatusInProgress) then
94 | begin
95 | Result := usInProgress;
96 | end else
97 | if (res is TSaveUrlJobStatusComplete) then
98 | begin
99 | Result := usComplete;
100 | end else
101 | begin
102 | Result := usFailed;
103 | end;
104 | finally
105 | res.Free();
106 | args.Free();
107 | end;
108 | end;
109 |
110 | procedure TDropboxManager.Close;
111 | begin
112 | if (FClient <> nil) then
113 | begin
114 | FClient.Abort();
115 | end;
116 | end;
117 |
118 | constructor TDropboxManager.Create;
119 | begin
120 | inherited Create();
121 | FClient := nil;
122 | end;
123 |
124 | procedure TDropboxManager.CreateFolder(const APath: string);
125 | var
126 | args: TCreateFolderArg;
127 | res: TFolderMetadata;
128 | begin
129 | args := nil;
130 | res := nil;
131 | try
132 | args := TCreateFolderArg.Create();
133 | args.Path := APath;
134 |
135 | res := GetClient().Files.CreateFolder(args);
136 |
137 | finally
138 | res.Free();
139 | args.Free();
140 | end;
141 | end;
142 |
143 | procedure TDropboxManager.Delete(const APath: string);
144 | var
145 | args: TDeleteArg;
146 | res: TMetadata;
147 | begin
148 | args := nil;
149 | res := nil;
150 | try
151 | args := TDeleteArg.Create();
152 | args.Path := APath;
153 |
154 | res := GetClient().Files.Delete(args);
155 |
156 | finally
157 | res.Free();
158 | args.Free();
159 | end;
160 | end;
161 |
162 | destructor TDropboxManager.Destroy;
163 | begin
164 | Close();
165 | FClient.Free();
166 |
167 | inherited Destroy();
168 | end;
169 |
170 | procedure TDropboxManager.Download(const ASourceFile: string; ADestination: TStream);
171 | var
172 | args: TDownloadArg;
173 | res: TFileMetadata;
174 | begin
175 | args := nil;
176 | res := nil;
177 | try
178 | args := TDownloadArg.Create();
179 | args.Path := ASourceFile;
180 |
181 | res := GetClient().Files.Download(args, ADestination);
182 |
183 | finally
184 | res.Free();
185 | args.Free();
186 | end;
187 | end;
188 |
189 | function TDropboxManager.GetClient: TDropboxClient;
190 | var
191 | credential: TDropboxOAuthCredential;
192 | initializer: TServiceInitializer;
193 | begin
194 | if (FClient = nil) then
195 | begin
196 | credential := TDropboxOAuthCredential.Create();
197 | initializer := TDropboxServiceInitializer.Create(credential, 'Clever Disk Manager');
198 | FClient := TDropboxClient.Create(initializer);
199 |
200 | credential.ClientID := ClientID;
201 | credential.ClientSecret := ClientSecret;
202 | credential.RedirectURL := RedirectURL;
203 | end;
204 | Result := FClient;
205 | end;
206 |
207 | procedure TDropboxManager.CollectFolderList(AListFolderResult: TListFolderResult; AList: TStrings);
208 | var
209 | entry: TMetaData;
210 | begin
211 | for entry in AListFolderResult.Entries do
212 | begin
213 | if (entry is TFileMetadata) then
214 | begin
215 | AList.Add((entry as TFileMetadata).PathDisplay);
216 | end else
217 | if (entry is TFolderMetadata) then
218 | begin
219 | AList.Add(' ' + (entry as TFolderMetadata).PathDisplay);
220 | end else
221 | if (entry is TDeletedMetadata) then
222 | begin
223 | AList.Add(' ' + (entry as TDeletedMetadata).PathDisplay);
224 | end else
225 | begin
226 | AList.Add(' ' + entry.Tag);
227 | end;
228 | end;
229 | end;
230 |
231 | procedure TDropboxManager.ListFolder(const APath: string; AList: TStrings);
232 | var
233 | args: TListFolderArg;
234 | continueArgs: TListFolderContinueArg;
235 | res: TListFolderResult;
236 | begin
237 | AList.BeginUpdate();
238 | args := nil;
239 | continueArgs := nil;
240 | res := nil;
241 | try
242 | AList.Clear();
243 |
244 | args := TListFolderArg.Create();
245 | args.Path := APath;
246 |
247 | continueArgs := TListFolderContinueArg.Create();
248 |
249 | res := GetClient().Files.ListFolder(args);
250 | CollectFolderList(res, AList);
251 |
252 | while (res.HasMore) do
253 | begin
254 | continueArgs.Cursor := res.Cursor;
255 |
256 | FreeAndNil(res);
257 | res := GetClient().Files.ListFolderContinue(continueArgs);
258 | CollectFolderList(res, AList);
259 | end;
260 | finally
261 | res.Free();
262 | continueArgs.Free();
263 | args.Free();
264 | AList.EndUpdate();
265 | end;
266 | end;
267 |
268 | procedure TDropboxManager.Move(const AFromPath, AToPath: string);
269 | var
270 | args: TRelocationArg;
271 | res: TMetadata;
272 | begin
273 | args := nil;
274 | res := nil;
275 | try
276 | args := TRelocationArg.Create();
277 | args.FromPath := AFromPath;
278 | args.ToPath := AToPath;
279 | args.AllowSharedFolder := True;
280 |
281 | res := GetClient().Files.Move(args);
282 |
283 | finally
284 | res.Free();
285 | args.Free();
286 | end;
287 | end;
288 |
289 | procedure TDropboxManager.CollectSearchList(ASearchResult: TSearchResult; AList: TStrings);
290 | var
291 | match: TSearchMatch;
292 | begin
293 | for match in ASearchResult.Matches do
294 | begin
295 | if (match.Metadata is TFileMetadata) then
296 | begin
297 | AList.Add((match.Metadata as TFileMetadata).PathDisplay);
298 | end else
299 | if (match.Metadata is TFolderMetadata) then
300 | begin
301 | AList.Add(' ' + (match.Metadata as TFolderMetadata).PathDisplay);
302 | end else
303 | if (match.Metadata is TDeletedMetadata) then
304 | begin
305 | AList.Add(' ' + (match.Metadata as TDeletedMetadata).PathDisplay);
306 | end else
307 | begin
308 | AList.Add(' ' + match.Metadata.Tag);
309 | end;
310 | end;
311 | end;
312 |
313 | procedure TDropboxManager.Copy(const AFromPath, AToPath: string);
314 | var
315 | args: TRelocationArg;
316 | res: TMetadata;
317 | begin
318 | args := nil;
319 | res := nil;
320 | try
321 | args := TRelocationArg.Create();
322 | args.FromPath := AFromPath;
323 | args.ToPath := AToPath;
324 |
325 | res := GetClient().Files.Copy(args);
326 |
327 | finally
328 | res.Free();
329 | args.Free();
330 | end;
331 | end;
332 |
333 | function TDropboxManager.SaveUrl(const APath, AUrl: string): string;
334 | var
335 | args: TSaveUrlArg;
336 | res: TSaveUrlResult;
337 | begin
338 | args := nil;
339 | res := nil;
340 | try
341 | args := TSaveUrlArg.Create();
342 | args.Path := APath;
343 | args.Url := AUrl;
344 |
345 | res := GetClient().Files.SaveUrl(args);
346 |
347 | if (res is TSaveUrlResultAsyncJobId) then
348 | begin
349 | Result := (res as TSaveUrlResultAsyncJobId).AsyncJobId;
350 | end else
351 | begin
352 | Result := '';
353 | end;
354 | finally
355 | res.Free();
356 | args.Free();
357 | end;
358 | end;
359 |
360 | procedure TDropboxManager.Search(const APath, AQuery: string; ASearchDeleted: Boolean; AList: TStrings);
361 | var
362 | args: TSearchArg;
363 | res: TSearchResult;
364 | begin
365 | AList.BeginUpdate();
366 | args := nil;
367 | res := nil;
368 | try
369 | AList.Clear();
370 |
371 | args := TSearchArg.Create();
372 | args.Path := APath;
373 | args.Query := AQuery;
374 |
375 | if ASearchDeleted then
376 | begin
377 | args.Mode := TDeletedFilenameSearchMode.Create();
378 | end;
379 |
380 | res := GetClient().Files.Search(args);
381 | CollectSearchList(res, AList);
382 |
383 | while (res.More) do
384 | begin
385 | args.Start := res.Start;
386 |
387 | FreeAndNil(res);
388 | res := GetClient().Files.Search(args);
389 | CollectSearchList(res, AList);
390 | end;
391 |
392 | finally
393 | res.Free();
394 | args.Free();
395 | AList.EndUpdate();
396 | end;
397 | end;
398 |
399 | procedure TDropboxManager.Upload(ASource: TStream; const ADestinationFile: string);
400 | var
401 | args: TCommitInfo;
402 | res: TFileMetadata;
403 | begin
404 | args := nil;
405 | res := nil;
406 | try
407 | args := TCommitInfo.Create();
408 | args.Path := ADestinationFile;
409 |
410 | res := GetClient().Files.Upload(args, ASource);
411 |
412 | finally
413 | res.Free();
414 | args.Free();
415 | end;
416 | end;
417 |
418 | end.
419 |
--------------------------------------------------------------------------------
/src/DropboxApi.Requests.pas:
--------------------------------------------------------------------------------
1 | {
2 | Copyright (C) 2017 by Clever Components
3 |
4 | Author: Sergey Shirokov
5 |
6 | Website: www.CleverComponents.com
7 |
8 | This file is part of Dropbox Client Library for Delphi.
9 |
10 | Dropbox Client Library for Delphi is free software:
11 | you can redistribute it and/or modify it under the terms of
12 | the GNU Lesser General Public License version 3
13 | as published by the Free Software Foundation and appearing in the
14 | included file COPYING.LESSER.
15 |
16 | Dropbox Client Library for Delphi is distributed in the hope
17 | that it will be useful, but WITHOUT ANY WARRANTY; without even the
18 | implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
19 | See the GNU Lesser General Public License for more details.
20 |
21 | You should have received a copy of the GNU Lesser General Public License
22 | along with Dropbox Client Library. If not, see .
23 |
24 | The current version of Dropbox Client Client Library for Delphi needs for
25 | the non-free library Clever Internet Suite. This is a drawback,
26 | and we suggest the task of changing
27 | the program so that it does the same job without the non-free library.
28 | Anyone who thinks of doing substantial further work on the program,
29 | first may free it from dependence on the non-free library.
30 | }
31 |
32 | unit DropboxApi.Requests;
33 |
34 | interface
35 |
36 | uses
37 | System.Classes, DropboxApi, DropboxApi.Data;
38 |
39 | type
40 | TFilesCreateFolderRequest = class(TServiceRequest)
41 | strict private
42 | FCreateFolderArg: TCreateFolderArg;
43 | public
44 | constructor Create(AService: TService; ACreateFolderArg: TCreateFolderArg);
45 |
46 | function Execute: TFolderMetadata; override;
47 | end;
48 |
49 | TFilesDeleteRequest = class(TServiceRequest)
50 | strict private
51 | FDeleteArg: TDeleteArg;
52 | public
53 | constructor Create(AService: TService; ADeleteArg: TDeleteArg);
54 |
55 | function Execute: TMetadata; override;
56 | end;
57 |
58 | TFilesListFolderRequest = class(TServiceRequest)
59 | strict private
60 | FListFolderArg: TListFolderArg;
61 | public
62 | constructor Create(AService: TService; AListFolderArg: TListFolderArg);
63 |
64 | function Execute: TListFolderResult; override;
65 | end;
66 |
67 | TFilesListFolderContinueRequest = class(TServiceRequest)
68 | strict private
69 | FListFolderContinueArg: TListFolderContinueArg;
70 | public
71 | constructor Create(AService: TService; AListFolderContinueArg: TListFolderContinueArg);
72 |
73 | function Execute: TListFolderResult; override;
74 | end;
75 |
76 | TFilesUploadRequest = class(TServiceRequest)
77 | strict private
78 | FCommitInfo: TCommitInfo;
79 | FBody: TStream;
80 | public
81 | constructor Create(AService: TService; ACommitInfo: TCommitInfo; ABody: TStream);
82 |
83 | function Execute: TFileMetadata; override;
84 | end;
85 |
86 | TFilesDownloadRequest = class(TServiceRequest)
87 | strict private
88 | FDownloadArg: TDownloadArg;
89 | FBody: TStream;
90 | public
91 | constructor Create(AService: TService; ADownloadArg: TDownloadArg; ABody: TStream);
92 |
93 | function Execute: TFileMetadata; override;
94 | end;
95 |
96 | TFilesSearchRequest = class(TServiceRequest)
97 | strict private
98 | FSearchArg: TSearchArg;
99 | public
100 | constructor Create(AService: TService; ASearchArg: TSearchArg);
101 |
102 | function Execute: TSearchResult; override;
103 | end;
104 |
105 | TFilesCopyRequest = class(TServiceRequest)
106 | strict private
107 | FRelocationArg: TRelocationArg;
108 | public
109 | constructor Create(AService: TService; ARelocationArg: TRelocationArg);
110 |
111 | function Execute: TMetadata; override;
112 | end;
113 |
114 | TFilesMoveRequest = class(TServiceRequest)
115 | strict private
116 | FRelocationArg: TRelocationArg;
117 | public
118 | constructor Create(AService: TService; ARelocationArg: TRelocationArg);
119 |
120 | function Execute: TMetadata; override;
121 | end;
122 |
123 | TFilesSaveUrlRequest = class(TServiceRequest)
124 | strict private
125 | FSaveUrlArg: TSaveUrlArg;
126 | public
127 | constructor Create(AService: TService; ASaveUrlArg: TSaveUrlArg);
128 |
129 | function Execute: TSaveUrlResult; override;
130 | end;
131 |
132 | TFilesSaveUrlCheckJobStatusRequest = class(TServiceRequest)
133 | strict private
134 | FPollArg: TPollArg;
135 | public
136 | constructor Create(AService: TService; APollArg: TPollArg);
137 |
138 | function Execute: TSaveUrlJobStatus; override;
139 | end;
140 |
141 | implementation
142 |
143 | { TFilesListFolderRequest }
144 |
145 | constructor TFilesListFolderRequest.Create(AService: TService; AListFolderArg: TListFolderArg);
146 | begin
147 | inherited Create(AService);
148 | FListFolderArg := AListFolderArg;
149 | end;
150 |
151 | function TFilesListFolderRequest.Execute: TListFolderResult;
152 | var
153 | request, response: string;
154 | begin
155 | request := Service.Initializer.JsonSerializer.ObjectToJson(FListFolderArg);
156 | response := Service.Initializer.HttpClient.RpcEndPointRequest('https://api.dropboxapi.com/2/files/list_folder', request);
157 | Result := Service.Initializer.JsonSerializer.JsonToObject(TListFolderResult, response) as TListFolderResult;
158 | end;
159 |
160 | { TFilesCreateFolderRequest }
161 |
162 | constructor TFilesCreateFolderRequest.Create(AService: TService; ACreateFolderArg: TCreateFolderArg);
163 | begin
164 | inherited Create(AService);
165 | FCreateFolderArg := ACreateFolderArg;
166 | end;
167 |
168 | function TFilesCreateFolderRequest.Execute: TFolderMetadata;
169 | var
170 | request, response: string;
171 | begin
172 | request := Service.Initializer.JsonSerializer.ObjectToJson(FCreateFolderArg);
173 | response := Service.Initializer.HttpClient.RpcEndPointRequest('https://api.dropboxapi.com/2/files/create_folder', request);
174 | Result := Service.Initializer.JsonSerializer.JsonToObject(TFolderMetadata, response) as TFolderMetadata;
175 | end;
176 |
177 | { TFilesDeleteRequest }
178 |
179 | constructor TFilesDeleteRequest.Create(AService: TService; ADeleteArg: TDeleteArg);
180 | begin
181 | inherited Create(AService);
182 | FDeleteArg := ADeleteArg;
183 | end;
184 |
185 | function TFilesDeleteRequest.Execute: TMetadata;
186 | var
187 | request, response: string;
188 | begin
189 | request := Service.Initializer.JsonSerializer.ObjectToJson(FDeleteArg);
190 | response := Service.Initializer.HttpClient.RpcEndPointRequest('https://api.dropboxapi.com/2/files/delete', request);
191 | Result := Service.Initializer.JsonSerializer.JsonToObject(TMetadata, response) as TMetadata;
192 | end;
193 |
194 | { TFilesListFolderContinueRequest }
195 |
196 | constructor TFilesListFolderContinueRequest.Create(AService: TService; AListFolderContinueArg: TListFolderContinueArg);
197 | begin
198 | inherited Create(AService);
199 | FListFolderContinueArg := AListFolderContinueArg;
200 | end;
201 |
202 | function TFilesListFolderContinueRequest.Execute: TListFolderResult;
203 | var
204 | request, response: string;
205 | begin
206 | request := Service.Initializer.JsonSerializer.ObjectToJson(FListFolderContinueArg);
207 | response := Service.Initializer.HttpClient.RpcEndPointRequest('https://api.dropboxapi.com/2/files/list_folder/continue', request);
208 | Result := Service.Initializer.JsonSerializer.JsonToObject(TListFolderResult, response) as TListFolderResult;
209 | end;
210 |
211 | { TFilesUploadRequest }
212 |
213 | constructor TFilesUploadRequest.Create(AService: TService; ACommitInfo: TCommitInfo; ABody: TStream);
214 | begin
215 | inherited Create(AService);
216 |
217 | FCommitInfo := ACommitInfo;
218 | FBody := ABody;
219 | end;
220 |
221 | function TFilesUploadRequest.Execute: TFileMetadata;
222 | var
223 | request, response: string;
224 | begin
225 | request := Service.Initializer.JsonSerializer.ObjectToJson(FCommitInfo);
226 | response := Service.Initializer.HttpClient.ContentUploadEndPointRequest('https://content.dropboxapi.com/2/files/upload', request, FBody);
227 | Result := Service.Initializer.JsonSerializer.JsonToObject(TFileMetadata, response) as TFileMetadata;
228 | end;
229 |
230 | { TFilesDownloadRequest }
231 |
232 | constructor TFilesDownloadRequest.Create(AService: TService; ADownloadArg: TDownloadArg; ABody: TStream);
233 | begin
234 | inherited Create(AService);
235 |
236 | FDownloadArg := ADownloadArg;
237 | FBody := ABody;
238 | end;
239 |
240 | function TFilesDownloadRequest.Execute: TFileMetadata;
241 | var
242 | request, response: string;
243 | begin
244 | request := Service.Initializer.JsonSerializer.ObjectToJson(FDownloadArg);
245 | response := Service.Initializer.HttpClient.ContentDownloadEndPointRequest('https://content.dropboxapi.com/2/files/download', request, FBody);
246 | Result := Service.Initializer.JsonSerializer.JsonToObject(TFileMetadata, response) as TFileMetadata;
247 | end;
248 |
249 | { TFilesSearchRequest }
250 |
251 | constructor TFilesSearchRequest.Create(AService: TService; ASearchArg: TSearchArg);
252 | begin
253 | inherited Create(AService);
254 | FSearchArg := ASearchArg;
255 | end;
256 |
257 | function TFilesSearchRequest.Execute: TSearchResult;
258 | var
259 | request, response: string;
260 | begin
261 | request := Service.Initializer.JsonSerializer.ObjectToJson(FSearchArg);
262 | response := Service.Initializer.HttpClient.RpcEndPointRequest('https://api.dropboxapi.com/2/files/search', request);
263 | Result := Service.Initializer.JsonSerializer.JsonToObject(TSearchResult, response) as TSearchResult;
264 | end;
265 |
266 | { TFilesCopyRequest }
267 |
268 | constructor TFilesCopyRequest.Create(AService: TService; ARelocationArg: TRelocationArg);
269 | begin
270 | inherited Create(AService);
271 | FRelocationArg := ARelocationArg;
272 | end;
273 |
274 | function TFilesCopyRequest.Execute: TMetadata;
275 | var
276 | request, response: string;
277 | begin
278 | request := Service.Initializer.JsonSerializer.ObjectToJson(FRelocationArg);
279 | response := Service.Initializer.HttpClient.RpcEndPointRequest('https://api.dropboxapi.com/2/files/copy', request);
280 | Result := Service.Initializer.JsonSerializer.JsonToObject(TMetadata, response) as TMetadata;
281 | end;
282 |
283 | { TFilesMoveRequest }
284 |
285 | constructor TFilesMoveRequest.Create(AService: TService; ARelocationArg: TRelocationArg);
286 | begin
287 | inherited Create(AService);
288 | FRelocationArg := ARelocationArg;
289 | end;
290 |
291 | function TFilesMoveRequest.Execute: TMetadata;
292 | var
293 | request, response: string;
294 | begin
295 | FRelocationArg.AllowSharedFolder := True;
296 |
297 | request := Service.Initializer.JsonSerializer.ObjectToJson(FRelocationArg);
298 | response := Service.Initializer.HttpClient.RpcEndPointRequest('https://api.dropboxapi.com/2/files/move', request);
299 | Result := Service.Initializer.JsonSerializer.JsonToObject(TMetadata, response) as TMetadata;
300 | end;
301 |
302 | { TFilesSaveUrlRequest }
303 |
304 | constructor TFilesSaveUrlRequest.Create(AService: TService; ASaveUrlArg: TSaveUrlArg);
305 | begin
306 | inherited Create(AService);
307 | FSaveUrlArg := ASaveUrlArg;
308 | end;
309 |
310 | function TFilesSaveUrlRequest.Execute: TSaveUrlResult;
311 | var
312 | request, response: string;
313 | begin
314 | request := Service.Initializer.JsonSerializer.ObjectToJson(FSaveUrlArg);
315 | response := Service.Initializer.HttpClient.RpcEndPointRequest('https://api.dropboxapi.com/2/files/save_url', request);
316 | Result := Service.Initializer.JsonSerializer.JsonToObject(TSaveUrlResult, response) as TSaveUrlResult;
317 | end;
318 |
319 | { TFilesSaveUrlCheckJobStatusRequest }
320 |
321 | constructor TFilesSaveUrlCheckJobStatusRequest.Create(AService: TService; APollArg: TPollArg);
322 | begin
323 | inherited Create(AService);
324 | FPollArg := APollArg;
325 | end;
326 |
327 | function TFilesSaveUrlCheckJobStatusRequest.Execute: TSaveUrlJobStatus;
328 | var
329 | request, response: string;
330 | begin
331 | request := Service.Initializer.JsonSerializer.ObjectToJson(FPollArg);
332 | response := Service.Initializer.HttpClient.RpcEndPointRequest('https://api.dropboxapi.com/2/files/save_url/check_job_status', request);
333 | Result := Service.Initializer.JsonSerializer.JsonToObject(TSaveUrlJobStatus, response) as TSaveUrlJobStatus;
334 | end;
335 |
336 | end.
337 |
--------------------------------------------------------------------------------
/src/DropboxApi.Data.pas:
--------------------------------------------------------------------------------
1 | {
2 | Copyright (C) 2017 by Clever Components
3 |
4 | Author: Sergey Shirokov
5 |
6 | Website: www.CleverComponents.com
7 |
8 | This file is part of Dropbox Client Library for Delphi.
9 |
10 | Dropbox Client Library for Delphi is free software:
11 | you can redistribute it and/or modify it under the terms of
12 | the GNU Lesser General Public License version 3
13 | as published by the Free Software Foundation and appearing in the
14 | included file COPYING.LESSER.
15 |
16 | Dropbox Client Library for Delphi is distributed in the hope
17 | that it will be useful, but WITHOUT ANY WARRANTY; without even the
18 | implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
19 | See the GNU Lesser General Public License for more details.
20 |
21 | You should have received a copy of the GNU Lesser General Public License
22 | along with Dropbox Client Library. If not, see .
23 |
24 | The current version of Dropbox Client Client Library for Delphi needs for
25 | the non-free library Clever Internet Suite. This is a drawback,
26 | and we suggest the task of changing
27 | the program so that it does the same job without the non-free library.
28 | Anyone who thinks of doing substantial further work on the program,
29 | first may free it from dependence on the non-free library.
30 | }
31 |
32 | unit DropboxApi.Data;
33 |
34 | interface
35 |
36 | uses
37 | System.Classes, clJsonSerializerBase;
38 | type
39 | TError = class
40 | strict private
41 | FTag: string;
42 | public
43 | [TclJsonString('.tag')]
44 | property Tag: string read FTag write FTag;
45 | end;
46 |
47 | TListFolderArg = class
48 | strict private
49 | FPath: string;
50 | FRecursive: Boolean;
51 | FIncludeMediaInfo: Boolean;
52 | FIncludeDeleted: Boolean;
53 | FIncludeHasExplicitSharedMembers: Boolean;
54 | public
55 | [TclJsonRequired]
56 | [TclJsonString('path')]
57 | property Path: string read FPath write FPath;
58 |
59 | [TclJsonProperty('recursive')]
60 | property Recursive: Boolean read FRecursive write FRecursive;
61 |
62 | [TclJsonProperty('include_media_info')]
63 | property IncludeMediaInfo: Boolean read FIncludeMediaInfo write FIncludeMediaInfo;
64 |
65 | [TclJsonProperty('include_deleted')]
66 | property IncludeDeleted: Boolean read FIncludeDeleted write FIncludeDeleted;
67 |
68 | [TclJsonProperty('include_has_explicit_shared_members')]
69 | property IncludeHasExplicitSharedMembers: Boolean read FIncludeHasExplicitSharedMembers write FIncludeHasExplicitSharedMembers;
70 | end;
71 |
72 | TListFolderContinueArg = class
73 | strict private
74 | FCursor: string;
75 | public
76 | [TclJsonString('cursor')]
77 | property Cursor: string read FCursor write FCursor;
78 | end;
79 |
80 | [TclJsonTypeNameMap('.tag', 'file', 'DropboxApi.Data.TFileMetadata')]
81 | [TclJsonTypeNameMap('.tag', 'folder', 'DropboxApi.Data.TFolderMetadata')]
82 | [TclJsonTypeNameMap('.tag', 'deleted', 'DropboxApi.Data.TDeletedMetadata')]
83 | TMetadata = class
84 | strict private
85 | FTag: string;
86 | public
87 | [TclJsonString('.tag')]
88 | property Tag: string read FTag write FTag;
89 | end;
90 |
91 | TFileSharingInfo = class
92 | strict private
93 | FParentSharedFolderId: string;
94 | FModifiedBy: string;
95 | FReadOnly: Boolean;
96 | public
97 | [TclJsonProperty('read_only')]
98 | property ReadOnly: Boolean read FReadOnly write FReadOnly;
99 |
100 | [TclJsonString('parent_shared_folder_id')]
101 | property ParentSharedFolderId: string read FParentSharedFolderId write FParentSharedFolderId;
102 |
103 | [TclJsonString('modified_by')]
104 | property ModifiedBy: string read FModifiedBy write FModifiedBy;
105 | end;
106 |
107 | TFileMetadata = class(TMetadata)
108 | strict private
109 | FRev: string;
110 | FName: string;
111 | FPathDisplay: string;
112 | FPathLower: string;
113 | FId: string;
114 | FSize: Int64;
115 | FHasExplicitSharedMembers: Boolean;
116 | FServerModified: string;
117 | FClientModified: string;
118 | FSharingInfo: TFileSharingInfo;
119 |
120 | procedure SetSharingInfo(const Value: TFileSharingInfo);
121 | public
122 | constructor Create;
123 | destructor Destroy; override;
124 |
125 | [TclJsonString('name')]
126 | property Name: string read FName write FName;
127 |
128 | [TclJsonString('id')]
129 | property Id: string read FId write FId;
130 |
131 | [TclJsonString('client_modified')]
132 | property ClientModified: string read FClientModified write FClientModified;
133 |
134 | [TclJsonString('server_modified')]
135 | property ServerModified: string read FServerModified write FServerModified;
136 |
137 | [TclJsonString('rev')]
138 | property Rev: string read FRev write FRev;
139 |
140 | [TclJsonProperty('size')]
141 | property Size: Int64 read FSize write FSize;
142 |
143 | [TclJsonString('path_lower')]
144 | property PathLower: string read FPathLower write FPathLower;
145 |
146 | [TclJsonString('path_display')]
147 | property PathDisplay: string read FPathDisplay write FPathDisplay;
148 |
149 | //media_info
150 |
151 | [TclJsonProperty('sharing_info')]
152 | property SharingInfo: TFileSharingInfo read FSharingInfo write SetSharingInfo;
153 |
154 | //property_groups
155 |
156 | [TclJsonProperty('has_explicit_shared_members')]
157 | property HasExplicitSharedMembers: Boolean read FHasExplicitSharedMembers write FHasExplicitSharedMembers;
158 | end;
159 |
160 | TFolderSharingInfo = class
161 | strict private
162 | FTraverseOnly: Boolean;
163 | FSharedFolderId: string;
164 | FParentSharedFolderId: string;
165 | FReadOnly: Boolean;
166 | FNoAccess: Boolean;
167 | public
168 | [TclJsonProperty('read_only')]
169 | property ReadOnly: Boolean read FReadOnly write FReadOnly;
170 |
171 | [TclJsonString('parent_shared_folder_id')]
172 | property ParentSharedFolderId: string read FParentSharedFolderId write FParentSharedFolderId;
173 |
174 | [TclJsonString('shared_folder_id')]
175 | property SharedFolderId: string read FSharedFolderId write FSharedFolderId;
176 |
177 | [TclJsonProperty('traverse_only')]
178 | property TraverseOnly: Boolean read FTraverseOnly write FTraverseOnly;
179 |
180 | [TclJsonProperty('no_access')]
181 | property NoAccess: Boolean read FNoAccess write FNoAccess;
182 | end;
183 |
184 | TFolderMetadata = class(TMetadata)
185 | strict private
186 | FName: string;
187 | FPathDisplay: string;
188 | FPathLower: string;
189 | FId: string;
190 | FSharingInfo: TFolderSharingInfo;
191 |
192 | procedure SetSharingInfo(const Value: TFolderSharingInfo);
193 | public
194 | constructor Create;
195 | destructor Destroy; override;
196 |
197 | [TclJsonString('name')]
198 | property Name: string read FName write FName;
199 |
200 | [TclJsonString('id')]
201 | property Id: string read FId write FId;
202 |
203 | [TclJsonString('path_lower')]
204 | property PathLower: string read FPathLower write FPathLower;
205 |
206 | [TclJsonString('path_display')]
207 | property PathDisplay: string read FPathDisplay write FPathDisplay;
208 |
209 | [TclJsonProperty('sharing_info')]
210 | property SharingInfo: TFolderSharingInfo read FSharingInfo write SetSharingInfo;
211 |
212 | //property_groups
213 | end;
214 |
215 | TDeletedMetadata = class(TMetadata)
216 | strict private
217 | FName: string;
218 | FPathDisplay: string;
219 | FPathLower: string;
220 | public
221 | constructor Create;
222 |
223 | [TclJsonString('name')]
224 | property Name: string read FName write FName;
225 |
226 | [TclJsonString('path_lower')]
227 | property PathLower: string read FPathLower write FPathLower;
228 |
229 | [TclJsonString('path_display')]
230 | property PathDisplay: string read FPathDisplay write FPathDisplay;
231 | end;
232 |
233 | TListFolderResult = class
234 | strict private
235 | FEntries: TArray;
236 | FCursor: string;
237 | FHasMore: Boolean;
238 |
239 | procedure SetEntries(const Value: TArray);
240 | public
241 | constructor Create;
242 | destructor Destroy; override;
243 |
244 | [TclJsonProperty('entries')]
245 | property Entries: TArray read FEntries write SetEntries;
246 |
247 | [TclJsonString('cursor')]
248 | property Cursor: string read FCursor write FCursor;
249 |
250 | [TclJsonProperty('has_more')]
251 | property HasMore: Boolean read FHasMore write FHasMore;
252 | end;
253 |
254 | TCreateFolderArg = class
255 | strict private
256 | FPath: string;
257 | FAutoRename: Boolean;
258 | public
259 | [TclJsonString('path')]
260 | property Path: string read FPath write FPath;
261 |
262 | [TclJsonProperty('autorename')]
263 | property AutoRename: Boolean read FAutoRename write FAutoRename;
264 | end;
265 |
266 | TDeleteArg = class
267 | strict private
268 | FPath: string;
269 | public
270 | [TclJsonString('path')]
271 | property Path: string read FPath write FPath;
272 | end;
273 |
274 | [TclJsonTypeNameMap('.tag', 'add', 'DropboxApi.Data.TAddWriteMode')]
275 | [TclJsonTypeNameMap('.tag', 'overwrite', 'DropboxApi.Data.TOverwriteWriteMode')]
276 | [TclJsonTypeNameMap('.tag', 'update', 'DropboxApi.Data.TUpdateWriteMode')]
277 | TWriteMode = class
278 | strict private
279 | FTag: string;
280 | public
281 | [TclJsonString('.tag')]
282 | property Tag: string read FTag write FTag;
283 | end;
284 |
285 | TAddWriteMode = class(TWriteMode)
286 | public
287 | constructor Create;
288 | end;
289 |
290 | TOverwriteWriteMode = class(TWriteMode)
291 | public
292 | constructor Create;
293 | end;
294 |
295 | TUpdateWriteMode = class(TWriteMode)
296 | strict private
297 | FUpdate: string;
298 | public
299 | constructor Create;
300 |
301 | [TclJsonString('update')]
302 | property Update: string read FUpdate write FUpdate;
303 | end;
304 |
305 | TCommitInfo = class
306 | strict private
307 | FPath: string;
308 | FMode: TWriteMode;
309 | FMute: Boolean;
310 | FAutoRename: Boolean;
311 | FClientModified: string;
312 |
313 | procedure SetMode(const Value: TWriteMode);
314 | public
315 | constructor Create;
316 | destructor Destroy; override;
317 |
318 | [TclJsonString('path')]
319 | property Path: string read FPath write FPath;
320 |
321 | [TclJsonProperty('mode')]
322 | property Mode: TWriteMode read FMode write SetMode;
323 |
324 | [TclJsonProperty('autorename')]
325 | property AutoRename: Boolean read FAutoRename write FAutoRename;
326 |
327 | [TclJsonProperty('client_modified')]
328 | property ClientModified: string read FClientModified write FClientModified;
329 |
330 | [TclJsonProperty('mute')]
331 | property Mute: Boolean read FMute write FMute;
332 | end;
333 |
334 | TDownloadArg = class
335 | strict private
336 | FPath: string;
337 | public
338 | [TclJsonString('path')]
339 | property Path: string read FPath write FPath;
340 | end;
341 |
342 | [TclJsonTypeNameMap('.tag', 'filename', 'DropboxApi.Data.TFileNameSearchMode')]
343 | [TclJsonTypeNameMap('.tag', 'filename_and_content', 'DropboxApi.Data.TFilenameAndContentSearchMode')]
344 | [TclJsonTypeNameMap('.tag', 'deleted_filename', 'DropboxApi.Data.TDeletedFilenameSearchMode')]
345 | TSearchMode = class
346 | strict private
347 | FTag: string;
348 | public
349 | [TclJsonString('.tag')]
350 | property Tag: string read FTag write FTag;
351 | end;
352 |
353 | TFileNameSearchMode = class(TSearchMode)
354 | public
355 | constructor Create;
356 | end;
357 |
358 | TFilenameAndContentSearchMode = class(TSearchMode)
359 | public
360 | constructor Create;
361 | end;
362 |
363 | TDeletedFilenameSearchMode = class(TSearchMode)
364 | public
365 | constructor Create;
366 | end;
367 |
368 | TSearchArg = class
369 | strict private
370 | FPath: string;
371 | FQuery: string;
372 | FStart: Int64;
373 | FMaxResults: Int64;
374 | FMode: TSearchMode;
375 |
376 | procedure SetMode(const Value: TSearchMode);
377 | public
378 | constructor Create;
379 | destructor Destroy; override;
380 |
381 | [TclJsonRequired]
382 | [TclJsonString('path')]
383 | property Path: string read FPath write FPath;
384 |
385 | [TclJsonRequired]
386 | [TclJsonString('query')]
387 | property Query: string read FQuery write FQuery;
388 |
389 | [TclJsonProperty('start')]
390 | property Start: Int64 read FStart write FStart;
391 |
392 | [TclJsonProperty('max_results')]
393 | property MaxResults: Int64 read FMaxResults write FMaxResults;
394 |
395 | [TclJsonProperty('mode')]
396 | property Mode: TSearchMode read FMode write SetMode;
397 | end;
398 |
399 | [TclJsonTypeNameMap('.tag', 'filename', 'DropboxApi.Data.TFileNameSearchMatchType')]
400 | [TclJsonTypeNameMap('.tag', 'content', 'DropboxApi.Data.TContentSearchMatchType')]
401 | [TclJsonTypeNameMap('.tag', 'both', 'DropboxApi.Data.TBothSearchMatchType')]
402 | TSearchMatchType = class
403 | strict private
404 | FTag: string;
405 | public
406 | [TclJsonString('.tag')]
407 | property Tag: string read FTag write FTag;
408 | end;
409 |
410 | TFileNameSearchMatchType = class(TSearchMatchType)
411 | public
412 | constructor Create;
413 | end;
414 |
415 | TContentSearchMatchType = class(TSearchMatchType)
416 | public
417 | constructor Create;
418 | end;
419 |
420 | TBothSearchMatchType = class(TSearchMatchType)
421 | public
422 | constructor Create;
423 | end;
424 |
425 | TSearchMatch = class
426 | strict private
427 | FMatchType: TSearchMatchType;
428 | FMetadata: TMetadata;
429 |
430 | procedure SetMatchType(const Value: TSearchMatchType);
431 | procedure SetMetadata(const Value: TMetadata);
432 | public
433 | constructor Create;
434 | destructor Destroy; override;
435 |
436 | [TclJsonProperty('match_type')]
437 | property MatchType: TSearchMatchType read FMatchType write SetMatchType;
438 |
439 | [TclJsonProperty('metadata')]
440 | property Metadata: TMetadata read FMetadata write SetMetadata;
441 | end;
442 |
443 | TSearchResult = class
444 | strict private
445 | FMatches: TArray;
446 | FMore: Boolean;
447 | FStart: Int64;
448 |
449 | procedure SetMatches(const Value: TArray);
450 | public
451 | constructor Create;
452 | destructor Destroy; override;
453 |
454 | [TclJsonProperty('matches')]
455 | property Matches: TArray read FMatches write SetMatches;
456 |
457 | [TclJsonProperty('more')]
458 | property More: Boolean read FMore write FMore;
459 |
460 | [TclJsonProperty('start')]
461 | property Start: Int64 read FStart write FStart;
462 | end;
463 |
464 | TRelocationArg = class
465 | strict private
466 | FFromPath: string;
467 | FToPath: string;
468 | FAllowSharedFolder: Boolean;
469 | FAutoRename: Boolean;
470 | public
471 | [TclJsonString('from_path')]
472 | property FromPath: string read FFromPath write FFromPath;
473 |
474 | [TclJsonString('to_path')]
475 | property ToPath: string read FToPath write FToPath;
476 |
477 | [TclJsonProperty('allow_shared_folder')]
478 | property AllowSharedFolder: Boolean read FAllowSharedFolder write FAllowSharedFolder;
479 |
480 | [TclJsonProperty('autorename')]
481 | property AutoRename: Boolean read FAutoRename write FAutoRename;
482 | end;
483 |
484 | TSaveUrlArg = class
485 | strict private
486 | FPath: string;
487 | FUrl: string;
488 | public
489 | [TclJsonString('path')]
490 | property Path: string read FPath write FPath;
491 |
492 | [TclJsonString('url')]
493 | property Url: string read FUrl write FUrl;
494 | end;
495 |
496 | [TclJsonTypeNameMap('.tag', 'async_job_id', 'DropboxApi.Data.TSaveUrlResultAsyncJobId')]
497 | [TclJsonTypeNameMap('.tag', 'complete', 'DropboxApi.Data.TSaveUrlResultComplete')]
498 | TSaveUrlResult = class
499 | strict private
500 | FTag: string;
501 | public
502 | [TclJsonString('.tag')]
503 | property Tag: string read FTag write FTag;
504 | end;
505 |
506 | TSaveUrlResultAsyncJobId = class(TSaveUrlResult)
507 | strict private
508 | FAsyncJobId: string;
509 | public
510 | constructor Create;
511 |
512 | [TclJsonString('async_job_id')]
513 | property AsyncJobId: string read FAsyncJobId write FAsyncJobId;
514 | end;
515 |
516 | //TODO implement unions of different types without the common ancentor in json serializer
517 | //here must be the TFileMetadata class
518 | TSaveUrlResultComplete = class(TSaveUrlResult)
519 | public
520 | constructor Create;
521 | end;
522 |
523 | TPollArg = class
524 | strict private
525 | FAsyncJobId: string;
526 | public
527 | [TclJsonString('async_job_id')]
528 | property AsyncJobId: string read FAsyncJobId write FAsyncJobId;
529 | end;
530 |
531 | [TclJsonTypeNameMap('.tag', 'in_progress', 'DropboxApi.Data.TSaveUrlJobStatusInProgress')]
532 | [TclJsonTypeNameMap('.tag', 'complete', 'DropboxApi.Data.TSaveUrlJobStatusComplete')]
533 | [TclJsonTypeNameMap('.tag', 'failed', 'DropboxApi.Data.TSaveUrlJobStatusFailed')]
534 | TSaveUrlJobStatus = class
535 | strict private
536 | FTag: string;
537 | public
538 | [TclJsonString('.tag')]
539 | property Tag: string read FTag write FTag;
540 | end;
541 |
542 | TSaveUrlJobStatusInProgress = class(TSaveUrlJobStatus)
543 | public
544 | constructor Create;
545 | end;
546 |
547 | //TODO implement unions of different types without the common ancentor in json serializer
548 | //here must be the TFileMetadata class
549 | TSaveUrlJobStatusComplete = class(TSaveUrlJobStatus)
550 | public
551 | constructor Create;
552 | end;
553 |
554 | TSaveUrlJobStatusFailed = class(TSaveUrlJobStatus)
555 | public
556 | constructor Create;
557 | end;
558 |
559 | implementation
560 |
561 | { TListFolderResult }
562 |
563 | constructor TListFolderResult.Create;
564 | begin
565 | inherited Create();
566 | FEntries := nil;
567 | end;
568 |
569 | destructor TListFolderResult.Destroy;
570 | begin
571 | SetEntries(nil);
572 | inherited Destroy();
573 | end;
574 |
575 | procedure TListFolderResult.SetEntries(const Value: TArray);
576 | var
577 | obj: TObject;
578 | begin
579 | if (FEntries <> nil) then
580 | begin
581 | for obj in FEntries do
582 | begin
583 | obj.Free();
584 | end;
585 | end;
586 |
587 | FEntries := Value;
588 | end;
589 |
590 | { TFolderMetadata }
591 |
592 | constructor TFolderMetadata.Create;
593 | begin
594 | inherited Create();
595 |
596 | FSharingInfo := nil;
597 | Tag := 'folder';
598 | end;
599 |
600 | destructor TFolderMetadata.Destroy;
601 | begin
602 | FSharingInfo.Free();
603 | inherited Destroy();
604 | end;
605 |
606 | procedure TFolderMetadata.SetSharingInfo(const Value: TFolderSharingInfo);
607 | begin
608 | FSharingInfo.Free();
609 | FSharingInfo := Value;
610 | end;
611 |
612 | { TFileMetadata }
613 |
614 | constructor TFileMetadata.Create;
615 | begin
616 | inherited Create();
617 |
618 | FSharingInfo := nil;
619 | Tag := 'file';
620 | end;
621 |
622 | destructor TFileMetadata.Destroy;
623 | begin
624 | FSharingInfo.Free();
625 | inherited Destroy();
626 | end;
627 |
628 | procedure TFileMetadata.SetSharingInfo(const Value: TFileSharingInfo);
629 | begin
630 | FSharingInfo.Free();
631 | FSharingInfo := Value;
632 | end;
633 |
634 | { TCommitInfo }
635 |
636 | constructor TCommitInfo.Create;
637 | begin
638 | inherited Create();
639 | FMode := nil;
640 | end;
641 |
642 | destructor TCommitInfo.Destroy;
643 | begin
644 | SetMode(nil);
645 | inherited Destroy();
646 | end;
647 |
648 | procedure TCommitInfo.SetMode(const Value: TWriteMode);
649 | begin
650 | FMode.Free();
651 | FMode := Value;
652 | end;
653 |
654 | { TDeletedMetadata }
655 |
656 | constructor TDeletedMetadata.Create;
657 | begin
658 | inherited Create();
659 | Tag := 'deleted';
660 | end;
661 |
662 | { TAdd }
663 |
664 | constructor TAddWriteMode.Create;
665 | begin
666 | inherited Create();
667 | Tag := 'add';
668 | end;
669 |
670 | { TUpdate }
671 |
672 | constructor TUpdateWriteMode.Create;
673 | begin
674 | inherited Create();
675 | Tag := 'update';
676 | end;
677 |
678 | { TOverwrite }
679 |
680 | constructor TOverwriteWriteMode.Create;
681 | begin
682 | inherited Create();
683 | Tag := 'overwrite';
684 | end;
685 |
686 | { TFileName }
687 |
688 | constructor TFileNameSearchMode.Create;
689 | begin
690 | inherited Create();
691 | Tag := 'filename';
692 | end;
693 |
694 | { TFilenameAndContent }
695 |
696 | constructor TFilenameAndContentSearchMode.Create;
697 | begin
698 | inherited Create();
699 | Tag := 'filename_and_content';
700 | end;
701 |
702 | { TDeletedFilename }
703 |
704 | constructor TDeletedFilenameSearchMode.Create;
705 | begin
706 | inherited Create();
707 | Tag := 'deleted_filename';
708 | end;
709 |
710 | { TSearchArg }
711 |
712 | constructor TSearchArg.Create;
713 | begin
714 | inherited Create();
715 | FMode := nil;
716 | MaxResults := 100;
717 | end;
718 |
719 | destructor TSearchArg.Destroy;
720 | begin
721 | SetMode(nil);
722 | inherited Destroy();
723 | end;
724 |
725 | procedure TSearchArg.SetMode(const Value: TSearchMode);
726 | begin
727 | FMode.Free();
728 | FMode := Value;
729 | end;
730 |
731 | { TSearchResult }
732 |
733 | constructor TSearchResult.Create;
734 | begin
735 | inherited Create();
736 | FMatches := nil;
737 | end;
738 |
739 | destructor TSearchResult.Destroy;
740 | begin
741 | SetMatches(nil);
742 | inherited Destroy();
743 | end;
744 |
745 | procedure TSearchResult.SetMatches(const Value: TArray);
746 | var
747 | obj: TObject;
748 | begin
749 | if (FMatches <> nil) then
750 | begin
751 | for obj in FMatches do
752 | begin
753 | obj.Free();
754 | end;
755 | end;
756 |
757 | FMatches := Value;
758 | end;
759 |
760 | { TFileNameSearchMatchType }
761 |
762 | constructor TFileNameSearchMatchType.Create;
763 | begin
764 | inherited Create();
765 | Tag := 'filename';
766 | end;
767 |
768 | { TContentSearchMatchType }
769 |
770 | constructor TContentSearchMatchType.Create;
771 | begin
772 | inherited Create();
773 | Tag := 'content';
774 | end;
775 |
776 | { TBothSearchMatchType }
777 |
778 | constructor TBothSearchMatchType.Create;
779 | begin
780 | inherited Create();
781 | Tag := 'both';
782 | end;
783 |
784 | { TSearchMatch }
785 |
786 | constructor TSearchMatch.Create;
787 | begin
788 | inherited Create();
789 |
790 | FMatchType := nil;
791 | FMetadata := nil;
792 | end;
793 |
794 | destructor TSearchMatch.Destroy;
795 | begin
796 | SetMatchType(nil);
797 | SetMetadata(nil);
798 |
799 | inherited Destroy();
800 | end;
801 |
802 | procedure TSearchMatch.SetMatchType(const Value: TSearchMatchType);
803 | begin
804 | FMatchType.Free();
805 | FMatchType := Value;
806 | end;
807 |
808 | procedure TSearchMatch.SetMetadata(const Value: TMetadata);
809 | begin
810 | FMetadata.Free();
811 | FMetadata := Value;
812 | end;
813 |
814 | { TSaveUrlResultAsyncJobId }
815 |
816 | constructor TSaveUrlResultAsyncJobId.Create;
817 | begin
818 | inherited Create();
819 | Tag := 'async_job_id';
820 | end;
821 |
822 | { TSaveUrlResultComplete }
823 |
824 | constructor TSaveUrlResultComplete.Create;
825 | begin
826 | inherited Create();
827 | Tag := 'complete';
828 | end;
829 |
830 | { TSaveUrlJobStatusInProgress }
831 |
832 | constructor TSaveUrlJobStatusInProgress.Create;
833 | begin
834 | inherited Create();
835 | Tag := 'in_progress';
836 | end;
837 |
838 | { TSaveUrlJobStatusComplete }
839 |
840 | constructor TSaveUrlJobStatusComplete.Create;
841 | begin
842 | inherited Create();
843 | Tag := 'complete';
844 | end;
845 |
846 | { TSaveUrlJobStatusFailed }
847 |
848 | constructor TSaveUrlJobStatusFailed.Create;
849 | begin
850 | inherited Create();
851 | Tag := 'failed';
852 | end;
853 |
854 | procedure ForceReferenceToClass(C: TClass);
855 | begin
856 | end;
857 |
858 | initialization
859 | ForceReferenceToClass(TError);
860 | ForceReferenceToClass(TListFolderArg);
861 | ForceReferenceToClass(TListFolderContinueArg);
862 | ForceReferenceToClass(TMetadata);
863 | ForceReferenceToClass(TFileSharingInfo);
864 | ForceReferenceToClass(TFileMetadata);
865 | ForceReferenceToClass(TFolderSharingInfo);
866 | ForceReferenceToClass(TFolderMetadata);
867 | ForceReferenceToClass(TDeletedMetadata);
868 | ForceReferenceToClass(TListFolderResult);
869 | ForceReferenceToClass(TCreateFolderArg);
870 | ForceReferenceToClass(TDeleteArg);
871 | ForceReferenceToClass(TWriteMode);
872 | ForceReferenceToClass(TAddWriteMode);
873 | ForceReferenceToClass(TOverwriteWriteMode);
874 | ForceReferenceToClass(TUpdateWriteMode);
875 | ForceReferenceToClass(TCommitInfo);
876 | ForceReferenceToClass(TDownloadArg);
877 | ForceReferenceToClass(TSearchMode);
878 | ForceReferenceToClass(TFileNameSearchMode);
879 | ForceReferenceToClass(TFilenameAndContentSearchMode);
880 | ForceReferenceToClass(TDeletedFilenameSearchMode);
881 | ForceReferenceToClass(TSearchArg);
882 | ForceReferenceToClass(TSearchMatchType);
883 | ForceReferenceToClass(TFileNameSearchMatchType);
884 | ForceReferenceToClass(TContentSearchMatchType);
885 | ForceReferenceToClass(TBothSearchMatchType);
886 | ForceReferenceToClass(TSearchMatch);
887 | ForceReferenceToClass(TSearchResult);
888 | ForceReferenceToClass(TRelocationArg);
889 | ForceReferenceToClass(TSaveUrlArg);
890 | ForceReferenceToClass(TSaveUrlResult);
891 | ForceReferenceToClass(TSaveUrlResultAsyncJobId);
892 | ForceReferenceToClass(TSaveUrlResultComplete);
893 | ForceReferenceToClass(TPollArg);
894 | ForceReferenceToClass(TSaveUrlJobStatus);
895 | ForceReferenceToClass(TSaveUrlJobStatusInProgress);
896 | ForceReferenceToClass(TSaveUrlJobStatusComplete);
897 | ForceReferenceToClass(TSaveUrlJobStatusFailed);
898 |
899 | end.
900 |
--------------------------------------------------------------------------------