##// END OF EJS Templates
expect JSON reply to save
Min RK -
Show More
@@ -1,250 +1,251
1 // Copyright (c) IPython Development Team.
1 // Copyright (c) IPython Development Team.
2 // Distributed under the terms of the Modified BSD License.
2 // Distributed under the terms of the Modified BSD License.
3
3
4 define([
4 define([
5 'base/js/namespace',
5 'base/js/namespace',
6 'jquery',
6 'jquery',
7 'base/js/utils',
7 'base/js/utils',
8 ], function(IPython, $, utils) {
8 ], function(IPython, $, utils) {
9 var Contents = function(options) {
9 var Contents = function(options) {
10 /**
10 /**
11 * Constructor
11 * Constructor
12 *
12 *
13 * A contents handles passing file operations
13 * A contents handles passing file operations
14 * to the back-end. This includes checkpointing
14 * to the back-end. This includes checkpointing
15 * with the normal file operations.
15 * with the normal file operations.
16 *
16 *
17 * Parameters:
17 * Parameters:
18 * options: dictionary
18 * options: dictionary
19 * Dictionary of keyword arguments.
19 * Dictionary of keyword arguments.
20 * base_url: string
20 * base_url: string
21 */
21 */
22 this.base_url = options.base_url;
22 this.base_url = options.base_url;
23 };
23 };
24
24
25 /** Error type */
25 /** Error type */
26 Contents.DIRECTORY_NOT_EMPTY_ERROR = 'DirectoryNotEmptyError';
26 Contents.DIRECTORY_NOT_EMPTY_ERROR = 'DirectoryNotEmptyError';
27
27
28 Contents.DirectoryNotEmptyError = function() {
28 Contents.DirectoryNotEmptyError = function() {
29 // Constructor
29 // Constructor
30 //
30 //
31 // An error representing the result of attempting to delete a non-empty
31 // An error representing the result of attempting to delete a non-empty
32 // directory.
32 // directory.
33 this.message = 'A directory must be empty before being deleted.';
33 this.message = 'A directory must be empty before being deleted.';
34 };
34 };
35
35
36 Contents.DirectoryNotEmptyError.prototype = Object.create(Error.prototype);
36 Contents.DirectoryNotEmptyError.prototype = Object.create(Error.prototype);
37 Contents.DirectoryNotEmptyError.prototype.name =
37 Contents.DirectoryNotEmptyError.prototype.name =
38 Contents.DIRECTORY_NOT_EMPTY_ERROR;
38 Contents.DIRECTORY_NOT_EMPTY_ERROR;
39
39
40
40
41 Contents.prototype.api_url = function() {
41 Contents.prototype.api_url = function() {
42 var url_parts = [this.base_url, 'api/contents'].concat(
42 var url_parts = [this.base_url, 'api/contents'].concat(
43 Array.prototype.slice.apply(arguments));
43 Array.prototype.slice.apply(arguments));
44 return utils.url_join_encode.apply(null, url_parts);
44 return utils.url_join_encode.apply(null, url_parts);
45 };
45 };
46
46
47 /**
47 /**
48 * Creates a basic error handler that wraps a jqXHR error as an Error.
48 * Creates a basic error handler that wraps a jqXHR error as an Error.
49 *
49 *
50 * Takes a callback that accepts an Error, and returns a callback that can
50 * Takes a callback that accepts an Error, and returns a callback that can
51 * be passed directly to $.ajax, which will wrap the error from jQuery
51 * be passed directly to $.ajax, which will wrap the error from jQuery
52 * as an Error, and pass that to the original callback.
52 * as an Error, and pass that to the original callback.
53 *
53 *
54 * @method create_basic_error_handler
54 * @method create_basic_error_handler
55 * @param{Function} callback
55 * @param{Function} callback
56 * @return{Function}
56 * @return{Function}
57 */
57 */
58 Contents.prototype.create_basic_error_handler = function(callback) {
58 Contents.prototype.create_basic_error_handler = function(callback) {
59 if (!callback) {
59 if (!callback) {
60 return utils.log_ajax_error;
60 return utils.log_ajax_error;
61 }
61 }
62 return function(xhr, status, error) {
62 return function(xhr, status, error) {
63 callback(utils.wrap_ajax_error(xhr, status, error));
63 callback(utils.wrap_ajax_error(xhr, status, error));
64 };
64 };
65 };
65 };
66
66
67 /**
67 /**
68 * File Functions (including notebook operations)
68 * File Functions (including notebook operations)
69 */
69 */
70
70
71 /**
71 /**
72 * Get a file.
72 * Get a file.
73 *
73 *
74 * Calls success with file JSON model, or error with error.
74 * Calls success with file JSON model, or error with error.
75 *
75 *
76 * @method get
76 * @method get
77 * @param {String} path
77 * @param {String} path
78 * @param {Object} options
78 * @param {Object} options
79 * type : 'notebook', 'file', or 'directory'
79 * type : 'notebook', 'file', or 'directory'
80 * format: 'text' or 'base64'; only relevant for type: 'file'
80 * format: 'text' or 'base64'; only relevant for type: 'file'
81 */
81 */
82 Contents.prototype.get = function (path, options) {
82 Contents.prototype.get = function (path, options) {
83 /**
83 /**
84 * We do the call with settings so we can set cache to false.
84 * We do the call with settings so we can set cache to false.
85 */
85 */
86 var settings = {
86 var settings = {
87 processData : false,
87 processData : false,
88 cache : false,
88 cache : false,
89 type : "GET",
89 type : "GET",
90 dataType : "json",
90 dataType : "json",
91 };
91 };
92 var url = this.api_url(path);
92 var url = this.api_url(path);
93 params = {};
93 params = {};
94 if (options.type) { params.type = options.type; }
94 if (options.type) { params.type = options.type; }
95 if (options.format) { params.format = options.format; }
95 if (options.format) { params.format = options.format; }
96 return utils.promising_ajax(url + '?' + $.param(params), settings);
96 return utils.promising_ajax(url + '?' + $.param(params), settings);
97 };
97 };
98
98
99
99
100 /**
100 /**
101 * Creates a new untitled file or directory in the specified directory path.
101 * Creates a new untitled file or directory in the specified directory path.
102 *
102 *
103 * @method new
103 * @method new
104 * @param {String} path: the directory in which to create the new file/directory
104 * @param {String} path: the directory in which to create the new file/directory
105 * @param {Object} options:
105 * @param {Object} options:
106 * ext: file extension to use
106 * ext: file extension to use
107 * type: model type to create ('notebook', 'file', or 'directory')
107 * type: model type to create ('notebook', 'file', or 'directory')
108 */
108 */
109 Contents.prototype.new_untitled = function(path, options) {
109 Contents.prototype.new_untitled = function(path, options) {
110 var data = JSON.stringify({
110 var data = JSON.stringify({
111 ext: options.ext,
111 ext: options.ext,
112 type: options.type
112 type: options.type
113 });
113 });
114
114
115 var settings = {
115 var settings = {
116 processData : false,
116 processData : false,
117 type : "POST",
117 type : "POST",
118 data: data,
118 data: data,
119 dataType : "json",
119 dataType : "json",
120 };
120 };
121 return utils.promising_ajax(this.api_url(path), settings);
121 return utils.promising_ajax(this.api_url(path), settings);
122 };
122 };
123
123
124 Contents.prototype.delete = function(path) {
124 Contents.prototype.delete = function(path) {
125 var settings = {
125 var settings = {
126 processData : false,
126 processData : false,
127 type : "DELETE",
127 type : "DELETE",
128 dataType : "json",
128 dataType : "json",
129 };
129 };
130 var url = this.api_url(path);
130 var url = this.api_url(path);
131 return utils.promising_ajax(url, settings).catch(
131 return utils.promising_ajax(url, settings).catch(
132 // Translate certain errors to more specific ones.
132 // Translate certain errors to more specific ones.
133 function(error) {
133 function(error) {
134 // TODO: update IPEP27 to specify errors more precisely, so
134 // TODO: update IPEP27 to specify errors more precisely, so
135 // that error types can be detected here with certainty.
135 // that error types can be detected here with certainty.
136 if (error.xhr.status === 400) {
136 if (error.xhr.status === 400) {
137 throw new Contents.DirectoryNotEmptyError();
137 throw new Contents.DirectoryNotEmptyError();
138 }
138 }
139 throw error;
139 throw error;
140 }
140 }
141 );
141 );
142 };
142 };
143
143
144 Contents.prototype.rename = function(path, new_path) {
144 Contents.prototype.rename = function(path, new_path) {
145 var data = {path: new_path};
145 var data = {path: new_path};
146 var settings = {
146 var settings = {
147 processData : false,
147 processData : false,
148 type : "PATCH",
148 type : "PATCH",
149 data : JSON.stringify(data),
149 data : JSON.stringify(data),
150 dataType: "json",
150 dataType: "json",
151 contentType: 'application/json',
151 contentType: 'application/json',
152 };
152 };
153 var url = this.api_url(path);
153 var url = this.api_url(path);
154 return utils.promising_ajax(url, settings);
154 return utils.promising_ajax(url, settings);
155 };
155 };
156
156
157 Contents.prototype.save = function(path, model) {
157 Contents.prototype.save = function(path, model) {
158 /**
158 /**
159 * We do the call with settings so we can set cache to false.
159 * We do the call with settings so we can set cache to false.
160 */
160 */
161 var settings = {
161 var settings = {
162 processData : false,
162 processData : false,
163 type : "PUT",
163 type : "PUT",
164 dataType: "json",
164 data : JSON.stringify(model),
165 data : JSON.stringify(model),
165 contentType: 'application/json',
166 contentType: 'application/json',
166 };
167 };
167 var url = this.api_url(path);
168 var url = this.api_url(path);
168 return utils.promising_ajax(url, settings);
169 return utils.promising_ajax(url, settings);
169 };
170 };
170
171
171 Contents.prototype.copy = function(from_file, to_dir) {
172 Contents.prototype.copy = function(from_file, to_dir) {
172 /**
173 /**
173 * Copy a file into a given directory via POST
174 * Copy a file into a given directory via POST
174 * The server will select the name of the copied file
175 * The server will select the name of the copied file
175 */
176 */
176 var url = this.api_url(to_dir);
177 var url = this.api_url(to_dir);
177
178
178 var settings = {
179 var settings = {
179 processData : false,
180 processData : false,
180 type: "POST",
181 type: "POST",
181 data: JSON.stringify({copy_from: from_file}),
182 data: JSON.stringify({copy_from: from_file}),
182 dataType : "json",
183 dataType : "json",
183 };
184 };
184 return utils.promising_ajax(url, settings);
185 return utils.promising_ajax(url, settings);
185 };
186 };
186
187
187 /**
188 /**
188 * Checkpointing Functions
189 * Checkpointing Functions
189 */
190 */
190
191
191 Contents.prototype.create_checkpoint = function(path) {
192 Contents.prototype.create_checkpoint = function(path) {
192 var url = this.api_url(path, 'checkpoints');
193 var url = this.api_url(path, 'checkpoints');
193 var settings = {
194 var settings = {
194 type : "POST",
195 type : "POST",
195 dataType : "json",
196 dataType : "json",
196 };
197 };
197 return utils.promising_ajax(url, settings);
198 return utils.promising_ajax(url, settings);
198 };
199 };
199
200
200 Contents.prototype.list_checkpoints = function(path) {
201 Contents.prototype.list_checkpoints = function(path) {
201 var url = this.api_url(path, 'checkpoints');
202 var url = this.api_url(path, 'checkpoints');
202 var settings = {
203 var settings = {
203 type : "GET",
204 type : "GET",
204 cache: false,
205 cache: false,
205 dataType: "json",
206 dataType: "json",
206 };
207 };
207 return utils.promising_ajax(url, settings);
208 return utils.promising_ajax(url, settings);
208 };
209 };
209
210
210 Contents.prototype.restore_checkpoint = function(path, checkpoint_id) {
211 Contents.prototype.restore_checkpoint = function(path, checkpoint_id) {
211 var url = this.api_url(path, 'checkpoints', checkpoint_id);
212 var url = this.api_url(path, 'checkpoints', checkpoint_id);
212 var settings = {
213 var settings = {
213 type : "POST",
214 type : "POST",
214 };
215 };
215 return utils.promising_ajax(url, settings);
216 return utils.promising_ajax(url, settings);
216 };
217 };
217
218
218 Contents.prototype.delete_checkpoint = function(path, checkpoint_id) {
219 Contents.prototype.delete_checkpoint = function(path, checkpoint_id) {
219 var url = this.api_url(path, 'checkpoints', checkpoint_id);
220 var url = this.api_url(path, 'checkpoints', checkpoint_id);
220 var settings = {
221 var settings = {
221 type : "DELETE",
222 type : "DELETE",
222 };
223 };
223 return utils.promising_ajax(url, settings);
224 return utils.promising_ajax(url, settings);
224 };
225 };
225
226
226 /**
227 /**
227 * File management functions
228 * File management functions
228 */
229 */
229
230
230 /**
231 /**
231 * List notebooks and directories at a given path
232 * List notebooks and directories at a given path
232 *
233 *
233 * On success, load_callback is called with an array of dictionaries
234 * On success, load_callback is called with an array of dictionaries
234 * representing individual files or directories. Each dictionary has
235 * representing individual files or directories. Each dictionary has
235 * the keys:
236 * the keys:
236 * type: "notebook" or "directory"
237 * type: "notebook" or "directory"
237 * created: created date
238 * created: created date
238 * last_modified: last modified dat
239 * last_modified: last modified dat
239 * @method list_notebooks
240 * @method list_notebooks
240 * @param {String} path The path to list notebooks in
241 * @param {String} path The path to list notebooks in
241 */
242 */
242 Contents.prototype.list_contents = function(path) {
243 Contents.prototype.list_contents = function(path) {
243 return this.get(path, {type: 'directory'});
244 return this.get(path, {type: 'directory'});
244 };
245 };
245
246
246
247
247 IPython.Contents = Contents;
248 IPython.Contents = Contents;
248
249
249 return {'Contents': Contents};
250 return {'Contents': Contents};
250 });
251 });
General Comments 0
You need to be logged in to leave comments. Login now