Skip to content

Commit c0a8348

Browse files
author
Louis Brauer
committed
Futher support for all RPC calls and added support for file upload and download
1 parent be27257 commit c0a8348

5 files changed

+268
-90
lines changed

README.md

+73-8
Original file line numberDiff line numberDiff line change
@@ -7,19 +7,84 @@ A non-official wrapper around Dropbox API v2
77

88
TODO
99
====
10-
Exception handling
11-
Implement rest of API
10+
11+
- [ ] Better exception handling
12+
- [ ] Documentation on Uploading and Downloading files
1213

1314

1415
Usage
1516
====
1617

17-
> dropbox = require('dropbox')
18-
> dropbox.set_token "PUT_YOUR_ACCESS_TOKEN_HERE"
19-
20-
21-
For the full set of features consult the [documentation](http://louis77.github.io/lua-dropbox/) page.
22-
18+
## Setup
19+
20+
```lua
21+
dropbox = require('dropbox')
22+
dropbox.set_token "PUT_YOUR_ACCESS_TOKEN_HERE"
23+
```
24+
25+
## Files and folders
26+
27+
Example:
28+
29+
```lua
30+
result, err = dropbox.copy{
31+
from_path = 'source.txt',
32+
to_path = 'to_path'
33+
}
34+
```
35+
36+
The following calls to the RPC endpoints are supported and mapped 1:1 as
37+
described in the HTTP API documentation. The functions always return the
38+
original Dropbox response plus an error code, if there was an error.
39+
40+
Please lookup the [Dropbox API doc] for the details.(https://www.dropbox.com/developers/documentation/http/documentation)
41+
42+
```lua
43+
list_folder = 'files/list_folder',
44+
create_folder = 'files/create_folder',
45+
copy = 'files/copy',
46+
delete = 'files/delete',
47+
get_metadata = 'files/get_metadata',
48+
list_revisions = 'files/list_revisions',
49+
move = 'files/move',
50+
permanently_delete = 'files/permanently_delete',
51+
restore = 'files/restore',
52+
search = 'files/search'
53+
```
54+
55+
## Sharing
56+
57+
```lua
58+
add_folder_member = 'sharing/add_folder_member',
59+
check_job_status = 'sharing/check_job_status',
60+
check_share_job_status = 'sharing/check_share_job_status',
61+
create_shared_link_with_settings = 'sharing/create_shared_link_with_settings',
62+
get_folder_metadata = 'sharing/get_folder_metadata',
63+
get_shared_link_metadata = 'sharing/get_shared_link_metadata',
64+
list_folder_members = 'sharing/list_folder_members',
65+
list_folders = 'sharing/list_folders',
66+
list_shared_links = 'sharing/list_shared_links',
67+
modify_shared_link_settings = 'sharing/modify_shared_link_settings',
68+
mount_folder = 'sharing/mount_folder',
69+
relinquish_folder_membership = 'sharing/relinquish_folder_membership',
70+
remove_folder_member = 'sharing/remove_folder_member',
71+
revoke_shared_link = 'sharing/revoke_shared_link',
72+
share_folder = 'sharing/share_folder',
73+
transfer_folder = 'sharing/transfer_folder',
74+
unmount_folder = 'sharing/unmount_folder',
75+
unshare_folder = 'sharing/unshare_folder',
76+
update_folder_member = 'sharing/update_folder_member',
77+
update_folder_policy = 'sharing/update_folder_policy'
78+
```
79+
80+
## Account
81+
82+
```lua
83+
get_account = 'users/get_account',
84+
get_account_batch = 'users/get_account_batch',
85+
get_current_account = 'users/get_current_account',
86+
get_space_usage = 'users/get_space_usage'
87+
```
2388

2489

2590
Dependencies

lua-dropbox-0.1-0.rockspec

+1-1
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ description = {
1717
}
1818
dependencies = {
1919
"lua >= 5.1",
20-
"lua-requests-https >= 1.1"
20+
"lua-requests >= 1.1"
2121
}
2222

2323
build = {

src/dropbox.lua

+116-71
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
-- https://github.com/JakobGreen/lua-requests/wiki
88
local requests = require 'requests'
99
local json = require 'cjson.safe'
10+
-- https://github.com/jagt/pprint.lua
1011
local pp = require 'pprint'
1112

1213
local M = {}
@@ -15,6 +16,45 @@ local M = {}
1516

1617
local DROPBOX_RPC_ENDPOINT = 'https://api.dropboxapi.com/2/'
1718
local DROPBOX_CONTENT_ENDPOINT = 'https://content.dropboxapi.com/2/'
19+
local RPC_CALLS = {
20+
-- files
21+
list_folder = 'files/list_folder',
22+
create_folder = 'files/create_folder',
23+
copy = 'files/copy',
24+
delete = 'files/delete',
25+
get_metadata = 'files/get_metadata',
26+
list_revisions = 'files/list_revisions',
27+
move = 'files/move',
28+
permanently_delete = 'files/permanently_delete',
29+
restore = 'files/restore',
30+
search = 'files/search',
31+
-- sharing
32+
add_folder_member = 'sharing/add_folder_member',
33+
check_job_status = 'sharing/check_job_status',
34+
check_share_job_status = 'sharing/check_share_job_status',
35+
create_shared_link_with_settings = 'sharing/create_shared_link_with_settings',
36+
get_folder_metadata = 'sharing/get_folder_metadata',
37+
get_shared_link_metadata = 'sharing/get_shared_link_metadata',
38+
list_folder_members = 'sharing/list_folder_members',
39+
list_folders = 'sharing/list_folders',
40+
list_shared_links = 'sharing/list_shared_links',
41+
modify_shared_link_settings = 'sharing/modify_shared_link_settings',
42+
mount_folder = 'sharing/mount_folder',
43+
relinquish_folder_membership = 'sharing/relinquish_folder_membership',
44+
remove_folder_member = 'sharing/remove_folder_member',
45+
revoke_shared_link = 'sharing/revoke_shared_link',
46+
share_folder = 'sharing/share_folder',
47+
transfer_folder = 'sharing/transfer_folder',
48+
unmount_folder = 'sharing/unmount_folder',
49+
unshare_folder = 'sharing/unshare_folder',
50+
update_folder_member = 'sharing/update_folder_member',
51+
update_folder_policy = 'sharing/update_folder_policy',
52+
-- users
53+
get_account = 'users/get_account',
54+
get_account_batch = 'users/get_account_batch',
55+
get_current_account = 'users/get_current_account',
56+
get_space_usage = 'users/get_space_usage'
57+
}
1858

1959
-- Module vars
2060

@@ -23,7 +63,7 @@ local token
2363
-- Private functions
2464

2565
local function add_auth(tbl)
26-
tbl["Authorization"] = "Bearer "..token
66+
tbl["Authorization"] = "Bearer " .. token
2767
return tbl
2868
end
2969

@@ -32,24 +72,26 @@ local function json_resp(response)
3272
if response.status_code >= 400 then
3373
err = response.text
3474
end
35-
return response.json(), err
75+
local result = response.headers['dropbox-api-result'] and json.decode(response.headers['dropbox-api-result']) or response.json()
76+
return result, err
3677
end
3778

3879
local function make_rpc_request(reqfunc, endpoint, data)
39-
local headers = add_auth{
40-
["Content-Type"] = 'application/json'
41-
}
80+
local headers = add_auth{}
81+
if data then
82+
headers["Content-Type"] = 'application/json'
83+
end
4284
local response = reqfunc(DROPBOX_RPC_ENDPOINT .. endpoint, {
4385
headers = headers,
4486
data = data
4587
})
4688
return json_resp(response)
4789
end
4890

49-
local function make_content_request(reqfunc, endpoint, data, content)
91+
local function make_content_upload_request(reqfunc, endpoint, data, content)
5092
local headers = add_auth{
51-
["Content-Type"] = 'application/octet-stream',
52-
["Dropbox-API-Arg"] = json.encode(data)
93+
["Dropbox-API-Arg"] = json.encode(data),
94+
["Content-Type"] = 'application/octet-stream'
5395
}
5496
local response = reqfunc(DROPBOX_CONTENT_ENDPOINT .. endpoint, {
5597
headers = headers,
@@ -58,6 +100,32 @@ local function make_content_request(reqfunc, endpoint, data, content)
58100
return json_resp(response)
59101
end
60102

103+
local function make_content_download_request(reqfunc, endpoint, data)
104+
local headers = add_auth{
105+
["Dropbox-API-Arg"] = json.encode(data)
106+
}
107+
local response = reqfunc(DROPBOX_CONTENT_ENDPOINT .. endpoint, {
108+
headers = headers
109+
})
110+
return response.text, json_resp(response)
111+
end
112+
113+
114+
local magic_calls_mt = {}
115+
magic_calls_mt.__index = function(_, w)
116+
local call = RPC_CALLS[w]
117+
if not call then
118+
error("Unknown API method '"..w.."'")
119+
end
120+
return function(args) return make_rpc_request(requests.post, call, args) end
121+
end
122+
setmetatable(M, magic_calls_mt)
123+
124+
125+
local function list_folder_continue(cursor)
126+
return make_rpc_request(requests.post, 'files/list_folder/continue', {cursor=cursor})
127+
end
128+
61129
-- Public functions
62130

63131
--- Set the access token for your Dropbox account.
@@ -67,44 +135,6 @@ function M.set_token(tk)
67135
token = tk
68136
end
69137

70-
--- List contents of a folder.
71-
-- @string path Folder path, use empty string for ROOT level
72-
-- @bool recursive
73-
-- @bool include_media_info
74-
-- @bool include_deleted
75-
-- @see cursor
76-
-- @return Raw response, pass it to cursor() to iterate and paginate over the results
77-
-- @return Error message if error occured during operation
78-
-- otherwise you'll get only the first few hundred results
79-
function M.list_folder(path, recursive, include_media_info, include_deleted)
80-
-- https://www.dropbox.com/developers/documentation/http/documentation#files-list_folder
81-
local message = {
82-
path = path,
83-
recursive = recursive,
84-
include_media_info = include_media_info,
85-
include_deleted = include_deleted
86-
}
87-
return make_rpc_request(requests.post, 'files/list_folder', message)
88-
end
89-
90-
local function list_folder_continue(cursor)
91-
-- https://www.dropbox.com/developers/documentation/http/documentation#files-list_folder-continue
92-
local message = {
93-
cursor = cursor
94-
}
95-
return make_rpc_request(requests.post, 'files/list_folder/continue', message)
96-
end
97-
98-
--- Create a folder.
99-
-- @string path Folder path and name, e.g. "/Homework/NewFolder"
100-
-- @return Raw response
101-
-- @return Error message if error occured during operation
102-
function M.create_folder(path)
103-
local message = {
104-
path = path
105-
}
106-
return make_rpc_request(requests.post, 'files/create_folder', message)
107-
end
108138

109139
--- Iterate over a folder listing.
110140
-- @param res raw response from list_folder
@@ -127,45 +157,60 @@ end
127157
--- Upload (create) a file.
128158
-- Should only be used for smaller files.
129159
-- @string path Path of file
130-
-- @string data Raw contents of file, can be text or binary
160+
-- @string data String or file handle
131161
-- @return Raw response, contains meta info about created file
132162
-- @return Error message if error occured during operation
133-
function M.upload(path, data)
134-
-- https://www.dropbox.com/developers/documentation/http/documentation#files-upload
135-
-- TODO This function should only be used for small files,
136-
-- Dropbox limit 150 MB
163+
function M.upload(path, data, overwrite)
164+
local body = data
137165
local message = {
138166
path = path,
139-
mode = "add",
140-
autorename = true,
167+
mode = overwrite and "overwrite" or "add",
168+
autorename = false,
141169
mute = false
142170
}
143-
return make_content_request(requests.post, 'files/upload', message, data)
171+
if type(data) == 'userdata' and io.type(data) == 'file' then
172+
body = data:read("*a")
173+
end
174+
local result = make_content_upload_request(requests.post, 'files/upload', message, body)
175+
return result
144176
end
145177

146-
--- Copy a file.
147-
-- @string from_path Source file path
148-
-- @string to_path Destination file path
149-
-- @return Raw response
150-
-- @return Error message if error occured during operation
151-
function M.copy(from_path, to_path)
178+
function M.upload_session_start(chunk)
179+
return make_content_upload_request(requests.post, 'files/upload_session/start', nil, chunk)
180+
end
181+
182+
function M.upload_session_append(session_id, offset, chunk)
152183
local message = {
153-
from_path = from_path,
154-
to_path = to_path
184+
session_id = session_id,
185+
offset = offset
155186
}
156-
return make_rpc_request(requests.post, 'files/copy', message)
187+
return make_content_upload_request(requests.post, 'files/upload_session/append', message, chunk)
157188
end
158189

159-
--- Delete a file or folder.
160-
-- Will delete all the contents in a folder along with it.
161-
-- @string path Folder or file path, e.g. "/Homework/Folder"
162-
-- @return Raw response
163-
-- @return Error message if error occured during operation
164-
function M.delete(path)
190+
function M.upload_session_finish(session_id, offset, path, overwrite, chunk)
165191
local message = {
166-
path = path
192+
cursor = {
193+
session_id = session_id,
194+
offset = offset
195+
},
196+
commit = {
197+
path = path,
198+
mode = overwrite and "overwrite" or "add",
199+
autorename = false,
200+
mute = false
201+
}
167202
}
168-
return make_rpc_request(requests.post, 'files/delete', message)
203+
return make_content_upload_request(requests.post, 'files/upload_session/finish', message, chunk)
204+
end
205+
206+
--- Download file contents.
207+
-- Should only be used for smaller files. Full file content is stores in a string.
208+
-- @string path Path of file
209+
-- @return File content
210+
-- @return File meta info
211+
-- @return Error message if error occured during operation
212+
function M.download(path)
213+
return make_content_download_request(requests.get, 'files/download', path)
169214
end
170215

171216
return M

0 commit comments

Comments
 (0)