box-api 0.1.7 → 0.1.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/Gemfile.lock +1 -1
- data/box-api.gemspec +1 -1
- data/doc/Box.html +108 -0
- data/doc/Box/Account.html +1099 -0
- data/doc/Box/Api.html +3428 -0
- data/doc/Box/Api/AccountExceeded.html +130 -0
- data/doc/Box/Api/EmailInvalid.html +141 -0
- data/doc/Box/Api/EmailTaken.html +130 -0
- data/doc/Box/Api/ErrorStatus.html +130 -0
- data/doc/Box/Api/Exception.html +120 -0
- data/doc/Box/Api/Generic.html +130 -0
- data/doc/Box/Api/InvalidFolder.html +141 -0
- data/doc/Box/Api/InvalidInput.html +130 -0
- data/doc/Box/Api/InvalidName.html +130 -0
- data/doc/Box/Api/NameTaken.html +130 -0
- data/doc/Box/Api/NoAccess.html +130 -0
- data/doc/Box/Api/NoParent.html +130 -0
- data/doc/Box/Api/NotAuthorized.html +130 -0
- data/doc/Box/Api/Restricted.html +141 -0
- data/doc/Box/Api/SizeExceeded.html +130 -0
- data/doc/Box/Api/Unknown.html +130 -0
- data/doc/Box/Api/UnknownResponse.html +141 -0
- data/doc/Box/Api/UploadFailed.html +141 -0
- data/doc/Box/File.html +580 -0
- data/doc/Box/Folder.html +1078 -0
- data/doc/Box/Item.html +1884 -0
- data/doc/_index.html +342 -0
- data/doc/class_list.html +47 -0
- data/doc/css/common.css +1 -0
- data/doc/css/full_list.css +53 -0
- data/doc/css/style.css +320 -0
- data/doc/file.README.html +98 -0
- data/doc/file_list.html +49 -0
- data/doc/frames.html +13 -0
- data/doc/index.html +98 -0
- data/doc/js/app.js +205 -0
- data/doc/js/full_list.js +150 -0
- data/doc/js/jquery.js +16 -0
- data/doc/method_list.html +574 -0
- data/doc/top-level-namespace.html +103 -0
- data/examples/login.rb +4 -4
- data/lib/box/account.rb +168 -51
- data/lib/box/api.rb +174 -16
- data/lib/box/api/exceptions.rb +4 -0
- data/lib/box/file.rb +17 -4
- data/lib/box/folder.rb +85 -30
- data/lib/box/item.rb +89 -20
- data/spec/account_spec.rb +0 -4
- data/spec/folder_spec.rb +3 -9
- metadata +42 -4
data/lib/box/api/exceptions.rb
CHANGED
@@ -29,6 +29,10 @@ module Box
|
|
29
29
|
class AccountExceeded < Exception; end
|
30
30
|
class SizeExceeded < Exception; end
|
31
31
|
|
32
|
+
# Given a status, returning a cooresponding Exception class.
|
33
|
+
#
|
34
|
+
# @param [String] status The failing status to look for.
|
35
|
+
# @return [Exception] A coorespondng Exception.
|
32
36
|
def self.get_exception(status)
|
33
37
|
case status
|
34
38
|
# Common responses
|
data/lib/box/file.rb
CHANGED
@@ -1,15 +1,24 @@
|
|
1
1
|
require 'box/item'
|
2
2
|
|
3
3
|
module Box
|
4
|
+
# Represents a file stored on Box. Any attributes or actions typical to
|
5
|
+
# a Box file can be accessed through this class.
|
6
|
+
|
4
7
|
class File < Item
|
8
|
+
# (see Item.type)
|
5
9
|
def self.type; 'file'; end
|
6
10
|
|
7
|
-
#
|
11
|
+
# Download this file to the specified path.
|
12
|
+
#
|
13
|
+
# @param [String] path The path to write the file.
|
8
14
|
def download(path)
|
9
15
|
@api.download(path, id)
|
10
16
|
end
|
11
17
|
|
12
|
-
#
|
18
|
+
# Overwrite this file, using the file at the specified path
|
19
|
+
#
|
20
|
+
# @param [String] path The path to the file to upload.
|
21
|
+
# @return [File] self
|
13
22
|
def upload_overwrite(path)
|
14
23
|
info = @api.overwrite(path, id)['files']['file']
|
15
24
|
|
@@ -19,7 +28,11 @@ module Box
|
|
19
28
|
self
|
20
29
|
end
|
21
30
|
|
22
|
-
#
|
31
|
+
# Upload a new copy of this file. The name will be "file (#).ext"
|
32
|
+
# for the each additional copy.
|
33
|
+
#
|
34
|
+
# @param path (see #upload_overwrite)
|
35
|
+
# @return [File] The newly created file.
|
23
36
|
def upload_copy(path)
|
24
37
|
info = @api.new_copy(path, id)['files']['file']
|
25
38
|
parent.delete_info('files')
|
@@ -29,7 +42,7 @@ module Box
|
|
29
42
|
|
30
43
|
protected
|
31
44
|
|
32
|
-
#
|
45
|
+
# (see Item#get_info)
|
33
46
|
def get_info
|
34
47
|
@api.get_file_info(id)['info']
|
35
48
|
end
|
data/lib/box/folder.rb
CHANGED
@@ -2,12 +2,16 @@ require 'box/item'
|
|
2
2
|
require 'box/file'
|
3
3
|
|
4
4
|
module Box
|
5
|
-
|
6
|
-
|
5
|
+
# Represents a folder stored on Box. Any attributes or actions typical to
|
6
|
+
# a Box folder can be accessed through this class.
|
7
7
|
|
8
|
+
class Folder < Item
|
9
|
+
# (see Item.type)
|
8
10
|
def self.type; 'folder'; end
|
9
11
|
|
10
|
-
#
|
12
|
+
# (see Item#info)
|
13
|
+
# Files and folders will only be one-level deep, and {#tree} should be
|
14
|
+
# used if fetching deeper than that.
|
11
15
|
def info(refresh = false)
|
12
16
|
return self if @cached_info and not refresh
|
13
17
|
|
@@ -17,7 +21,16 @@ module Box
|
|
17
21
|
super
|
18
22
|
end
|
19
23
|
|
20
|
-
#
|
24
|
+
# Get the tree for this folder. The tree includes all sub folders and
|
25
|
+
# files, including their info. Uses a cached copy if avaliable,
|
26
|
+
# or else it is fetched from the api.
|
27
|
+
#
|
28
|
+
# @note Fetching the tree can take a long time for large folders. There
|
29
|
+
# is a trade-off between one {#tree} call and multiple {#info}
|
30
|
+
# calls, so use the one most relevant for your application.
|
31
|
+
#
|
32
|
+
# @param [Boolean] refresh Does not use the cached copy if true.
|
33
|
+
# @return [Folder] self
|
21
34
|
def tree(refresh = false)
|
22
35
|
return self if @cached_tree and not refresh
|
23
36
|
|
@@ -30,7 +43,12 @@ module Box
|
|
30
43
|
self
|
31
44
|
end
|
32
45
|
|
33
|
-
#
|
46
|
+
# Create a new folder using this folder as the parent.
|
47
|
+
#
|
48
|
+
# @param [String] name The name of the new folder.
|
49
|
+
# @param [Integer] share The shared status of the new folder. Defaults
|
50
|
+
# to not being shared.
|
51
|
+
# @return [Folder] The new folder.
|
34
52
|
def create(name, share = 0)
|
35
53
|
info = @api.create_folder(id, name, share)['folder']
|
36
54
|
|
@@ -39,7 +57,10 @@ module Box
|
|
39
57
|
Box::Folder.new(api, self, info)
|
40
58
|
end
|
41
59
|
|
42
|
-
#
|
60
|
+
# Upload a new file using this folder as the parent
|
61
|
+
#
|
62
|
+
# @param [String] path The path of the file on disk to upload.
|
63
|
+
# @return [File] The new file.
|
43
64
|
def upload(path)
|
44
65
|
info = @api.upload(path, id)['files']['file']
|
45
66
|
|
@@ -48,7 +69,29 @@ module Box
|
|
48
69
|
Box::File.new(api, self, info)
|
49
70
|
end
|
50
71
|
|
51
|
-
#
|
72
|
+
# Search for sub-items using criteria.
|
73
|
+
#
|
74
|
+
# @param [Hash] criteria The hash of criteria to use. Each key of
|
75
|
+
# the criteria will be called on each sub-item and tested
|
76
|
+
# for equality. This lets you use any method of {Item}, {Folder},
|
77
|
+
# and {File} as the criteria.
|
78
|
+
# @return [Array] An array of all sub-items that matched the criteria.
|
79
|
+
#
|
80
|
+
# @note The recursive option will call {#tree}, which can be slow for
|
81
|
+
# large folders.
|
82
|
+
# @note Any item method (as a symbol) can be used as criteria, which
|
83
|
+
# could cause major problems if used improperly.
|
84
|
+
#
|
85
|
+
# @example Find all sub-items with the name 'README'
|
86
|
+
# folder.search(:name => 'README')
|
87
|
+
#
|
88
|
+
# @example Recusively find a sub-item with the given path.
|
89
|
+
# folder.search(:path => '/test/file.mp4', :recursive => true)
|
90
|
+
#
|
91
|
+
# @example Recursively find all files with a given sha1.
|
92
|
+
# folder.search(:type => 'file', :sha1 => 'abcdefg', :recursive => true)
|
93
|
+
#
|
94
|
+
# TODO: Lookup YARD syntax for options hash.
|
52
95
|
def find(criteria)
|
53
96
|
recursive = criteria.delete(:recursive)
|
54
97
|
recursive = false if recursive == nil # default to false for performance reasons
|
@@ -58,24 +101,49 @@ module Box
|
|
58
101
|
find!(criteria, recursive)
|
59
102
|
end
|
60
103
|
|
104
|
+
# (see Item#force_cached_info)
|
105
|
+
def force_cached_info
|
106
|
+
create_sub_items(nil, Box::Folder)
|
107
|
+
create_sub_items(nil, Box::File)
|
108
|
+
|
109
|
+
super
|
110
|
+
end
|
111
|
+
|
112
|
+
# Consider the tree cached. This prevents an additional api
|
113
|
+
# when we know the item is fully fetched.
|
114
|
+
def force_cached_tree
|
115
|
+
@cached_tree = true
|
116
|
+
|
117
|
+
create_sub_items(nil, Box::Folder)
|
118
|
+
create_sub_items(nil, Box::File)
|
119
|
+
|
120
|
+
folders.each do |folder|
|
121
|
+
folder.force_cached_tree
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
61
125
|
protected
|
62
126
|
|
63
|
-
|
127
|
+
attr_accessor :cached_tree
|
128
|
+
|
129
|
+
# (see Item#get_info)
|
64
130
|
def get_info
|
65
131
|
@api.get_account_tree(id, 'onelevel')['tree']['folder']
|
66
132
|
end
|
67
133
|
|
68
|
-
#
|
134
|
+
# Fetch the folder tree from the api.
|
135
|
+
# @return [Hash] The folder tree.
|
69
136
|
def get_tree
|
70
|
-
@api.get_account_tree(id)['tree']['folder']
|
137
|
+
@api.get_account_tree(id, 'simple')['tree']['folder']
|
71
138
|
end
|
72
139
|
|
140
|
+
# (see Item#clear_info)
|
73
141
|
def clear_info
|
74
142
|
@cached_tree = false
|
75
143
|
super
|
76
144
|
end
|
77
145
|
|
78
|
-
#
|
146
|
+
# (see Item#update_info)
|
79
147
|
def update_info(info)
|
80
148
|
if folders = info.delete('folders')
|
81
149
|
create_sub_items(folders, Box::Folder)
|
@@ -88,7 +156,11 @@ module Box
|
|
88
156
|
super
|
89
157
|
end
|
90
158
|
|
91
|
-
#
|
159
|
+
# Create objects for the sub items.
|
160
|
+
#
|
161
|
+
# @param [Array] items Array of item info.
|
162
|
+
# @param [Item] item_class The class of the items in the Array.
|
163
|
+
# @return [Array] Array of {Item}s.
|
92
164
|
def create_sub_items(items, item_class)
|
93
165
|
@data[item_class.types] ||= Array.new
|
94
166
|
|
@@ -104,24 +176,7 @@ module Box
|
|
104
176
|
end
|
105
177
|
end
|
106
178
|
|
107
|
-
#
|
108
|
-
def force_cached_tree
|
109
|
-
create_sub_items(nil, Box::Folder)
|
110
|
-
create_sub_items(nil, Box::File)
|
111
|
-
|
112
|
-
files.each do |file|
|
113
|
-
file.cached_info = true
|
114
|
-
end
|
115
|
-
|
116
|
-
folders.each do |folder|
|
117
|
-
folder.cached_info = true
|
118
|
-
folder.cached_tree = true
|
119
|
-
|
120
|
-
folder.force_cached_tree
|
121
|
-
end
|
122
|
-
end
|
123
|
-
|
124
|
-
# search for any files/folders that match the criteria sent
|
179
|
+
# (see #find)
|
125
180
|
def find!(criteria, recursive)
|
126
181
|
matches = (files + folders).collect do |item| # search over our files and folders
|
127
182
|
match = criteria.all? do |key, value| # make sure all criteria pass
|
data/lib/box/item.rb
CHANGED
@@ -1,8 +1,24 @@
|
|
1
1
|
module Box
|
2
|
+
# Represents a folder or file stored on Box. Any attributes or actions
|
3
|
+
# typical to a Box item can be accessed through this class. The {Item}
|
4
|
+
# class contains only methods shared by {Folder} and {File}, and should
|
5
|
+
# not be instanciated directly.
|
6
|
+
|
2
7
|
class Item
|
3
|
-
|
4
|
-
attr_accessor :
|
8
|
+
# @return [Hash] The hash of info for this item.
|
9
|
+
attr_accessor :data
|
10
|
+
|
11
|
+
# @return [Api] The {Api} used by this item.
|
12
|
+
attr_accessor :api
|
13
|
+
|
14
|
+
# @return [Folder] The parent of this item.
|
15
|
+
attr_accessor :parent
|
5
16
|
|
17
|
+
# Create a new item representing either a file or folder.
|
18
|
+
#
|
19
|
+
# @param [Api] api The {Api} instance used to generate requests.
|
20
|
+
# @param [Folder] parent The {Folder} parent of this item.
|
21
|
+
# @param [Hash] info The hash of initial info for this item.
|
6
22
|
def initialize(api, parent, info)
|
7
23
|
@api = api
|
8
24
|
@parent = parent
|
@@ -11,17 +27,31 @@ module Box
|
|
11
27
|
update_info(info) # merges with the info hash, and renames some fields
|
12
28
|
end
|
13
29
|
|
14
|
-
# return
|
30
|
+
# @return [String] The string representation of this item.
|
15
31
|
def self.type; raise "Overwrite this method"; end
|
32
|
+
|
33
|
+
# @return [String] The plural string representation of this item.
|
16
34
|
def self.types; type + 's'; end
|
17
35
|
|
18
|
-
# should be a better way of doing this
|
36
|
+
# TODO: There should be a better way of doing this.
|
37
|
+
|
38
|
+
# (see .type)
|
19
39
|
def type; self.class.type; end
|
40
|
+
|
41
|
+
# (see .types)
|
20
42
|
def types; self.class.types; end
|
21
43
|
|
22
|
-
|
44
|
+
# @return [String] The id of this item.
|
45
|
+
def id
|
46
|
+
# overloads Object#id
|
47
|
+
@data['id']
|
48
|
+
end
|
23
49
|
|
24
|
-
#
|
50
|
+
# Get the info for this item. Uses a cached copy if avaliable,
|
51
|
+
# or else it is fetched from the api.
|
52
|
+
#
|
53
|
+
# @param [Boolean] refresh Does not use the cached copy if true.
|
54
|
+
# @return [Item] self
|
25
55
|
def info(refresh = false)
|
26
56
|
return self if @cached_info and not refresh
|
27
57
|
|
@@ -31,7 +61,10 @@ module Box
|
|
31
61
|
self
|
32
62
|
end
|
33
63
|
|
34
|
-
#
|
64
|
+
# Move this item to the destination folder.
|
65
|
+
#
|
66
|
+
# @param [Folder] destination The new parent folder to use.
|
67
|
+
# @return [Item] self
|
35
68
|
def move(destination)
|
36
69
|
@api.move(type, id, destination.id)
|
37
70
|
|
@@ -43,7 +76,12 @@ module Box
|
|
43
76
|
self
|
44
77
|
end
|
45
78
|
|
46
|
-
#
|
79
|
+
# Copy this item to the destination folder.
|
80
|
+
#
|
81
|
+
# @note Copying folders is not currently supported.
|
82
|
+
#
|
83
|
+
# @param [Folder] destination The parent folder to copy the item to.
|
84
|
+
# @return [Item] The new copy of this item.
|
47
85
|
def copy(destination)
|
48
86
|
@api.copy(type, id, destination.id)
|
49
87
|
|
@@ -52,7 +90,10 @@ module Box
|
|
52
90
|
self.class.new(api, destination, @data)
|
53
91
|
end
|
54
92
|
|
55
|
-
#
|
93
|
+
# Rename this item.
|
94
|
+
#
|
95
|
+
# @param [String] new_name The new name for the item.
|
96
|
+
# @return [Item] self
|
56
97
|
def rename(new_name)
|
57
98
|
@api.rename(type, id, new_name)
|
58
99
|
|
@@ -61,7 +102,10 @@ module Box
|
|
61
102
|
self
|
62
103
|
end
|
63
104
|
|
64
|
-
#
|
105
|
+
# Delete this item and all sub-items.
|
106
|
+
#
|
107
|
+
# @return [Item] self
|
108
|
+
# TODO: Return nil instead
|
65
109
|
def delete
|
66
110
|
@api.delete(type, id)
|
67
111
|
|
@@ -71,41 +115,62 @@ module Box
|
|
71
115
|
self
|
72
116
|
end
|
73
117
|
|
74
|
-
#
|
118
|
+
# Set the description of this item.
|
119
|
+
#
|
120
|
+
# @param [String] message The description message to use.
|
121
|
+
# @return [Item] self
|
75
122
|
def description(message)
|
76
123
|
@api.set_description(type, id, message)
|
77
124
|
|
78
125
|
self
|
79
126
|
end
|
80
127
|
|
81
|
-
#
|
128
|
+
# @return [String] The path of this item. This starts with a '/'.
|
82
129
|
def path
|
83
130
|
"#{ parent.path + '/' if parent }#{ name }"
|
84
131
|
end
|
85
132
|
|
86
|
-
#
|
133
|
+
# Provides an easy way to access this item's info.
|
134
|
+
#
|
135
|
+
# @example
|
136
|
+
# item.name # returns @data['name'] or fetches it if not cached
|
87
137
|
def method_missing(sym, *args, &block)
|
138
|
+
# TODO: Why not symbols?
|
139
|
+
# convert to a string
|
88
140
|
str = sym.to_s
|
89
141
|
|
90
142
|
# return the value if it already exists
|
91
143
|
return @data[str] if @data.key?(str)
|
92
144
|
|
93
|
-
# value didn't exist, so update the info
|
145
|
+
# value didn't exist, so try to update the info
|
94
146
|
self.info
|
95
147
|
|
96
|
-
# try again
|
148
|
+
# try returning the value again
|
97
149
|
return @data[str] if @data.key?(str)
|
98
150
|
|
99
151
|
# we didn't find a value, so it must be invalid
|
152
|
+
# call the normal method_missing function
|
100
153
|
super
|
101
154
|
end
|
102
155
|
|
156
|
+
# Consider the item cached. This prevents an additional api
|
157
|
+
# when we know the item is fully fetched.
|
158
|
+
def force_cached_info
|
159
|
+
@cached_info = true
|
160
|
+
end
|
161
|
+
|
103
162
|
protected
|
104
163
|
|
105
|
-
#
|
106
|
-
|
164
|
+
# Fetches this item's info from the api.
|
165
|
+
#
|
166
|
+
# @return [Hash] The info for the item.
|
167
|
+
def get_info; Hash.new; end
|
107
168
|
|
108
|
-
#
|
169
|
+
# Merges in the given info, making sure the fields are uniform.
|
170
|
+
# This is done because the api will occasionally return fields like
|
171
|
+
# 'file_id', but we want just 'id'.
|
172
|
+
#
|
173
|
+
# @param [Hash] info A hash to be merged this item's info
|
109
174
|
def update_info(info)
|
110
175
|
ninfo = Hash.new
|
111
176
|
|
@@ -118,13 +183,17 @@ module Box
|
|
118
183
|
@data.merge!(ninfo) # merge in the updated info
|
119
184
|
end
|
120
185
|
|
121
|
-
#
|
186
|
+
# Invalidates and deletes the cache for a specific field. This forces
|
187
|
+
# the item to lazy-load this field if it is requested.
|
188
|
+
#
|
189
|
+
# @param [String] field The field to delete.
|
122
190
|
def delete_info(field)
|
123
191
|
@cached_info = false
|
124
192
|
@data.delete(field)
|
125
193
|
end
|
126
194
|
|
127
|
-
#
|
195
|
+
# Invalidates and deletes the entire cache. This forces all info to be
|
196
|
+
# lazy-loaded if requested.
|
128
197
|
def clear_info
|
129
198
|
@cached_info = false
|
130
199
|
@data.clear
|
data/spec/account_spec.rb
CHANGED