rest api changes from big rename
[plstackapi.git] / planetstack / core / xoslib / static / js / xoslib / xos-backbone.js
1 if (! window.XOSLIB_LOADED ) {
2     window.XOSLIB_LOADED=true;
3
4     SLIVER_API = "/plstackapi/slivers/";
5     SLICE_API = "/plstackapi/slices/";
6     SLICEROLE_API = "/plstackapi/slice_roles/";
7     NODE_API = "/plstackapi/nodes/";
8     SITE_API = "/plstackapi/sites/";
9     USER_API = "/plstackapi/users/";
10     USERDEPLOYMENT_API = "/plstackapi/user_deployments/";
11     DEPLOYMENT_API = "/plstackapi/deployments/";
12     IMAGE_API = "/plstackapi/images/";
13     NETWORKTEMPLATE_API = "/plstackapi/networktemplates/";
14     NETWORK_API = "/plstackapi/networks/";
15     NETWORKSLIVER_API = "/plstackapi/networkslivers/";
16     SERVICE_API = "/plstackapi/services/";
17     SLICEPRIVILEGE_API = "/plstackapi/slice_privileges/";
18     NETWORKDEPLOYMENT_API = "/plstackapi/networkdeployments/";
19
20     /* changed as a side effect of the big rename
21     SLICEDEPLOYMENT_API = "/plstackapi/slice_deployments/";
22     USERDEPLOYMENT_API = "/plstackapi/user_deployments/";
23     */
24
25     SLICEDEPLOYMENT_API = "/plstackapi/slicedeployments/";
26     USERDEPLOYMENT_API = "/plstackapi/userdeployments/";
27
28     SLICEPLUS_API = "/xoslib/slicesplus/";
29
30     XOSModel = Backbone.Model.extend({
31         /* from backbone-tastypie.js */
32         //idAttribute: 'resource_uri',
33
34         /* from backbone-tastypie.js */
35         url: function() {
36                     var url = this.attributes.resource_uri;
37
38                     if (!url) {
39                         if (this.id) {
40                             url = this.urlRoot + this.id;
41                         } else {
42                             // this happens when creating a new model.
43                             url = this.urlRoot;
44                         }
45                     }
46
47                     if (!url) {
48                         // XXX I'm not sure this does anything useful
49                         url = ( _.isFunction( this.collection.url ) ? this.collection.url() : this.collection.url );
50                         url = url || this.urlRoot;
51                     }
52
53                     // remove any existing query parameters
54                     url && ( url.indexOf("?") > -1 ) && ( url = url.split("?")[0] );
55
56                     url && ( url += ( url.length > 0 && url.charAt( url.length - 1 ) === '/' ) ? '' : '/' );
57
58                     url && ( url += "?no_hyperlinks=1" );
59
60                     return url;
61             },
62
63             listMethods: function() {
64                 var res = [];\r
65                 for(var m in this) {\r
66                     if(typeof this[m] == "function") {\r
67                         res.push(m)\r
68                     }\r
69                 }\r
70                 return res;\r
71             }
72     });
73
74     XOSCollection = Backbone.Collection.extend({
75         objects: function() {
76                     return this.models.map(function(element) { return element.attributes; });
77                  },
78
79         initialize: function(){
80           this.isLoaded = false;
81           this.sortVar = 'name';\r
82           this.sortOrder = 'asc';\r
83           this.on( "sort", this.sorted );\r
84         },\r
85 \r
86         relatedCollections: [],\r
87         foreignCollections: [],\r
88 \r
89         sorted: function() {\r
90             this.isLoaded = true;\r
91         },\r
92 \r
93         simpleComparator: function( model ){\r
94           parts=this.sortVar.split(".");\r
95           result = model.get(parts[0]);\r
96           for (index=1; index<parts.length; ++index) {\r
97               result=result[parts[index]];\r
98           }\r
99           return result;\r
100         },\r
101 \r
102         comparator: function (left, right) {\r
103             var l = this.simpleComparator(left);\r
104             var r = this.simpleComparator(right);\r
105 \r
106             if (l === void 0) return -1;\r
107             if (r === void 0) return 1;\r
108 \r
109             if (this.sortOrder=="desc") {\r
110                 return l < r ? 1 : l > r ? -1 : 0;\r
111             } else {\r
112                 return l < r ? -1 : l > r ? 1 : 0;\r
113             }\r
114         },\r
115 \r
116         startPolling: function() {\r
117             if (!this._polling) {\r
118                 var collection=this;
119                 setInterval(function() { collection.fetch(); }, 10000);
120                 this._polling=true;
121                 this.fetch();
122             }
123         },
124
125         maybeFetch: function(options){
126                 // Helper function to fetch only if this collection has not been fetched before.
127             if(this._fetched){
128                     // If this has already been fetched, call the success, if it exists
129                 options.success && options.success();
130                 console.log("alreadyFetched");
131                 return;
132             }
133
134                 // when the original success function completes mark this collection as fetched
135             var self = this,
136             successWrapper = function(success){
137                 return function(){
138                     self._fetched = true;
139                     success && success.apply(this, arguments);
140                 };
141             };
142             options.success = successWrapper(options.success);
143             console.log("call fetch");
144             this.fetch(options);
145         },
146
147         getOrFetch: function(id, options){
148                 // Helper function to use this collection as a cache for models on the server
149             var model = this.get(id);
150
151             if(model){
152                 options.success && options.success(model);
153                 return;
154             }
155
156             model = new this.model({
157                 resource_uri: id
158             });
159
160             model.fetch(options);
161         },
162
163         filterBy: function(fieldName, value) {
164              filtered = this.filter(function(obj) {
165                  return obj.get(fieldName) == value;
166                  });
167              return new this.constructor(filtered);
168         },
169
170         /* from backbone-tastypie.js */
171         url: function( models ) {
172                     var url = this.urlRoot || ( models && models.length && models[0].urlRoot );
173                     url && ( url += ( url.length > 0 && url.charAt( url.length - 1 ) === '/' ) ? '' : '/' );
174
175                     // Build a url to retrieve a set of models. This assume the last part of each model's idAttribute
176                     // (set to 'resource_uri') contains the model's id.
177                     if ( models && models.length ) {
178                             var ids = _.map( models, function( model ) {
179                                             var parts = _.compact( model.id.split('/') );
180                                             return parts[ parts.length - 1 ];
181                                     });
182                             url += 'set/' + ids.join(';') + '/';
183                     }
184
185                     url && ( url += "?no_hyperlinks=1" );
186
187                     return url;
188             },
189
190         listMethods: function() {
191                 var res = [];\r
192                 for(var m in this) {\r
193                     if(typeof this[m] == "function") {\r
194                         res.push(m)\r
195                     }\r
196                 }\r
197                 return res;\r
198             },
199     });
200
201     function define_model(lib, attrs) {
202         modelName = attrs.modelName;
203         modelClassName = modelName;
204         collectionClassName = modelName + "Collection";
205         collectionName = modelName + "s";
206
207         modelAttrs = {}
208         collectionAttrs = {}
209
210         for (key in attrs) {
211             value = attrs[key];
212             if ($.inArray(key, ["urlRoot", "modelName"])>=0) {
213                 modelAttrs[key] = value;
214             }
215             if ($.inArray(key, ["urlRoot", "modelName", "relatedCollections", "foreignCollections"])>=0) {
216                 collectionAttrs[key] = value;
217             }
218         }
219
220         if (xosdefaults && xosdefaults[modelName]) {
221             modelAttrs["defaults"] = xosdefaults[modelName];
222         }
223
224         lib[modelName] = XOSModel.extend(modelAttrs);
225
226         collectionAttrs["model"] = lib[modelName];
227
228         lib[collectionClassName] = XOSCollection.extend(collectionAttrs);
229         lib[collectionName] = new lib[collectionClassName]();
230
231         lib.allCollectionNames.push(collectionName);
232     };
233
234     function xoslib() {
235         this.allCollectionNames = [];
236
237         define_model(this, {urlRoot: SLIVER_API,
238                             relatedCollections: {"networkSlivers": "sliver"},
239                             foreignCollections: ["slices", "deployments", "images", "nodes", "users"],
240                             modelName: "sliver"});
241
242         define_model(this, {urlRoot: SLICE_API,
243                            relatedCollections: {"slivers": "slice", "sliceDeployments": "slice", "slicePrivileges": "slice", "networks": "owner"},
244                            foreignCollections: ["services", "sites"],
245                            modelName: "slice"});
246
247         define_model(this, {urlRoot: SLICEDEPLOYMENT_API,
248                            foreignCollections: ["slices", "deployments"],
249                            modelName: "sliceDeployment"});
250
251         define_model(this, {urlRoot: SLICEPRIVILEGE_API,
252                             foreignCollections: ["slices", "users", "sliceRoles"],
253                             modelName: "slicePrivilege"});
254
255         define_model(this, {urlRoot: SLICEROLE_API,
256                             modelName: "sliceRole"});
257
258         define_model(this, {urlRoot: NODE_API,
259                             foreignCollections: ["sites", "deployments"],
260                             modelName: "node"});
261
262         define_model(this, {urlRoot: SITE_API,
263                             relatedCollections: {"users": "site", "slices": "site", "nodes": "site"},
264                             modelName: "site"});
265
266         define_model(this, {urlRoot: USER_API,
267                             relatedCollections: {"slicePrivileges": "user", "slices": "owner", "userDeployments": "user"},
268                             foreignCollections: ["sites"],
269                             modelName: "user"});
270
271         define_model(this, {urlRoot: USERDEPLOYMENT_API,
272                             foreignCollections: ["users","deployments"],
273                             modelName: "userDeployment"});
274
275         define_model(this, { urlRoot: DEPLOYMENT_API,
276                              relatedCollections: {"nodes": "deployment", "slivers": "deploymentNetwork", "networkDeployments": "deployment", "userDeployments": "deployment"},
277                              modelName: "deployment"});
278
279         define_model(this, {urlRoot: IMAGE_API,
280                             model: this.image,
281                             modelName: "image"});
282
283         define_model(this, {urlRoot: NETWORKTEMPLATE_API,
284                             modelName: "networkTemplate"});
285
286         define_model(this, {urlRoot: NETWORK_API,
287                             relatedCollections: {"networkDeployments": "network", "networkSlivers": "network"},
288                             foreignCollections: ["slices", "networkTemplates"],
289                             modelName: "network"});
290
291         define_model(this, {urlRoot: NETWORKSLIVER_API,
292                             modelName: "networkSliver"});
293
294         define_model(this, {urlRoot: NETWORKDEPLOYMENT_API,
295                             modelName: "networkDeployment"});
296
297         define_model(this, {urlRoot: SERVICE_API,
298                             modelName: "service"});
299
300         // enhanced REST
301         define_model(this, {urlRoot: SLICEPLUS_API,
302                             relatedCollections: {'slivers': "slice"},
303                             modelName: "slicePlus"});
304
305         this.listObjects = function() { return this.allCollectionNames; };
306     };
307
308     xos = new xoslib();
309
310     function getCookie(name) {
311         var cookieValue = null;\r
312         if (document.cookie && document.cookie != '') {\r
313             var cookies = document.cookie.split(';');\r
314             for (var i = 0; i < cookies.length; i++) {\r
315                 var cookie = jQuery.trim(cookies[i]);\r
316                 // Does this cookie string begin with the name we want?\r
317                 if (cookie.substring(0, name.length + 1) == (name + '=')) {\r
318                     cookieValue = decodeURIComponent(cookie.substring(name.length + 1));\r
319                     break;\r
320                 }\r
321             }\r
322         }\r
323         return cookieValue;\r
324     }
325
326     (function() {
327       var _sync = Backbone.sync;\r
328       Backbone.sync = function(method, model, options){\r
329         options.beforeSend = function(xhr){\r
330           var token = getCookie("csrftoken");\r
331           xhr.setRequestHeader('X-CSRFToken', token);\r
332         };\r
333         return _sync(method, model, options);\r
334       };\r
335     })();
336 }