box-api 0.1.7 → 0.1.8

Sign up to get free protection for your applications and to get access to all the features.
Files changed (50) hide show
  1. data/Gemfile.lock +1 -1
  2. data/box-api.gemspec +1 -1
  3. data/doc/Box.html +108 -0
  4. data/doc/Box/Account.html +1099 -0
  5. data/doc/Box/Api.html +3428 -0
  6. data/doc/Box/Api/AccountExceeded.html +130 -0
  7. data/doc/Box/Api/EmailInvalid.html +141 -0
  8. data/doc/Box/Api/EmailTaken.html +130 -0
  9. data/doc/Box/Api/ErrorStatus.html +130 -0
  10. data/doc/Box/Api/Exception.html +120 -0
  11. data/doc/Box/Api/Generic.html +130 -0
  12. data/doc/Box/Api/InvalidFolder.html +141 -0
  13. data/doc/Box/Api/InvalidInput.html +130 -0
  14. data/doc/Box/Api/InvalidName.html +130 -0
  15. data/doc/Box/Api/NameTaken.html +130 -0
  16. data/doc/Box/Api/NoAccess.html +130 -0
  17. data/doc/Box/Api/NoParent.html +130 -0
  18. data/doc/Box/Api/NotAuthorized.html +130 -0
  19. data/doc/Box/Api/Restricted.html +141 -0
  20. data/doc/Box/Api/SizeExceeded.html +130 -0
  21. data/doc/Box/Api/Unknown.html +130 -0
  22. data/doc/Box/Api/UnknownResponse.html +141 -0
  23. data/doc/Box/Api/UploadFailed.html +141 -0
  24. data/doc/Box/File.html +580 -0
  25. data/doc/Box/Folder.html +1078 -0
  26. data/doc/Box/Item.html +1884 -0
  27. data/doc/_index.html +342 -0
  28. data/doc/class_list.html +47 -0
  29. data/doc/css/common.css +1 -0
  30. data/doc/css/full_list.css +53 -0
  31. data/doc/css/style.css +320 -0
  32. data/doc/file.README.html +98 -0
  33. data/doc/file_list.html +49 -0
  34. data/doc/frames.html +13 -0
  35. data/doc/index.html +98 -0
  36. data/doc/js/app.js +205 -0
  37. data/doc/js/full_list.js +150 -0
  38. data/doc/js/jquery.js +16 -0
  39. data/doc/method_list.html +574 -0
  40. data/doc/top-level-namespace.html +103 -0
  41. data/examples/login.rb +4 -4
  42. data/lib/box/account.rb +168 -51
  43. data/lib/box/api.rb +174 -16
  44. data/lib/box/api/exceptions.rb +4 -0
  45. data/lib/box/file.rb +17 -4
  46. data/lib/box/folder.rb +85 -30
  47. data/lib/box/item.rb +89 -20
  48. data/spec/account_spec.rb +0 -4
  49. data/spec/folder_spec.rb +3 -9
  50. metadata +42 -4
@@ -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
@@ -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
- # download the file to the specified path
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
- # overwrite this file, using the file at the specified path
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
- # upload a new copy of this file, the name being 'file (#).ext' for the #th copy
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
- # get the file info
45
+ # (see Item#get_info)
33
46
  def get_info
34
47
  @api.get_file_info(id)['info']
35
48
  end
@@ -2,12 +2,16 @@ require 'box/item'
2
2
  require 'box/file'
3
3
 
4
4
  module Box
5
- class Folder < Item
6
- attr_accessor :cached_tree
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
- # override the existing info method so that we create empty folders/files first
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
- # use the cached tree or update it if requested
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
- # create a new folder using this folder as the parent
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
- # upload a new file using this folder as the parent
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
- # search for items using criteria
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
- # get the folder info
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
- # get the folder info and all nested items
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
- # overload Item#update_info to create the subobjects like Files and Folders
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
- # create the sub items, so they are objects rather than hashes
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
- # update the cached status of all sub items, as we got the entire tree
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
@@ -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
- attr_accessor :data, :api, :parent
4
- attr_accessor :cached_info
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 the string representation of this item (file or folder)
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
- def id; @data['id']; end # overwrite Object#id, which is not what we want
44
+ # @return [String] The id of this item.
45
+ def id
46
+ # overloads Object#id
47
+ @data['id']
48
+ end
23
49
 
24
- # use cached info or update it if requested
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
- # move the item to the destination folder
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
- # copy the file (folder not supported in the api) to the destination folder
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
- # rename the item
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
- # delete the item
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
- # set the description of the item
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
- # get the path, starting with /
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
- # use method_missing as to provide an easy way to access the item's properties
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
- # sub-classes are meant to implement this
106
- def get_info(*args); Hash.new; end
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
- # takes in a hash of info, cleans it, and merges it into the existing info
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
- # delete the cache for a specific info
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
- # delete the entire cache
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
@@ -9,10 +9,6 @@ describe Box::Account do
9
9
  @account = get_account(false)
10
10
  end
11
11
 
12
- it "gets a ticket" do
13
- @account.ticket.should_not == nil
14
- end
15
-
16
12
  it "fails to authorize without auth token" do
17
13
  @account.authorize.should == false
18
14
  end