Merge lp:~rharding/juju-gui/api0 into lp:juju-gui/experimental

Proposed by Richard Harding on 2013-03-20
Status: Work in progress
Proposed branch: lp:~rharding/juju-gui/api0
Merge into: lp:juju-gui/experimental
Diff against target: 402 lines (+264/-17) (has conflicts)
2 files modified
app/models/charm.js (+169/-13)
app/store/charm.js (+95/-4)
Text conflict in app/models/charm.js
To merge this branch: bzr merge lp:~rharding/juju-gui/api0
Reviewer Review Type Date Requested Status
Juju GUI Hackers 2013-03-20 Pending
Review via email: mp+154385@code.launchpad.net

Description of the change

TBD

To post a comment you must log in.

Unmerged revisions

416. By Richard Harding on 2013-03-05

Start to work on the api calls for the charmstore

415. By Richard Harding on 2013-03-04

Fix the broken stuff

414. By Richard Harding on 2013-03-04

Working on model code

413. By Richard Harding on 2013-03-04

start to work on model resolution

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'app/models/charm.js'
2--- app/models/charm.js 2013-03-11 13:51:08 +0000
3+++ app/models/charm.js 2013-03-20 14:43:53 +0000
4@@ -1,3 +1,4 @@
5+/*global YUI:false*/
6 'use strict';
7
8 /**
9@@ -10,6 +11,7 @@
10 YUI.add('juju-charm-models', function(Y) {
11
12 var models = Y.namespace('juju.models');
13+ // Check on the idea of the id.
14 var charmIdRe = /^(?:(\w+):)?(?:~(\S+)\/)?(\w+)\/(\S+?)-(\d+)$/;
15 var idElements = ['scheme', 'owner', 'series', 'package_name', 'revision'];
16 var simpleCharmIdRe = /^(?:(\w+):)?(?!:~)(\w+)$/;
17@@ -80,13 +82,20 @@
18
19 initializer: function() {
20 var id = this.get('id'),
21+<<<<<<< TREE
22 parts = parseCharmId(id),
23 self = this;
24 if (!parts) {
25+=======
26+ parts = id && charmIdRe.exec(id),
27+ self = this;
28+ if (!Y.Lang.isValue(id) || !parts) {
29+>>>>>>> MERGE-SOURCE
30 throw 'Developers must initialize charms with a well-formed id.';
31 }
32 this.loaded = false;
33 this.on('load', function() { this.loaded = true; });
34+<<<<<<< TREE
35 Y.Object.each(
36 parts,
37 function(value, key) { self.set(key, value); });
38@@ -97,6 +106,16 @@
39 tmp.unshift('~' + owner);
40 }
41 this.set('full_name', tmp.join('/'));
42+=======
43+ parts.shift();
44+ var attrs = Y.Array.zip(idElements, parts);
45+ Y.each(
46+ attrs,
47+ function(pair) {
48+ self.set(pair[0], pair[1]);
49+ }
50+ );
51+>>>>>>> MERGE-SOURCE
52 },
53
54 sync: function(action, options, callback) {
55@@ -120,25 +139,25 @@
56 }
57 }
58 );
59- } else if (Y.Lang.isValue(options.loadByPath)) {
60+ } else if (Y.Lang.isValue(options.charm)) {
61 // This is a charm store.
62- options.loadByPath(
63- this.get('charm_store_path'),
64- { success: function(response) {
65+ options.charm(
66+ this.get('charm_store_path'), {
67+ success: function(response) {
68 callback(false, response);
69 },
70 failure: function(response) {
71 callback(true, response);
72 }
73- });
74+ });
75 } else {
76- throw 'You must supply a get_charm or loadByPath function.';
77+ throw 'You must supply a CharmStore.charm or loadByPath function.';
78 }
79 },
80
81 parse: function() {
82 var data = Charm.superclass.parse.apply(this, arguments),
83- self = this;
84+ self = this;
85 data.is_subordinate = data.subordinate;
86 Y.each(data, function(value, key) {
87 if (!value ||
88@@ -157,7 +176,7 @@
89 // Official charms sort before owned charms.
90 // If !X.owner, that means it is owned by charmers.
91 var owner = this.get('owner'),
92- otherOwner = other.get('owner');
93+ otherOwner = other.get('owner');
94 if (!owner && otherOwner) {
95 return -1;
96 } else if (owner && !otherOwner) {
97@@ -183,11 +202,33 @@
98 return Y.Lang.isString(val) && !!charmIdRe.exec(val);
99 }
100 },
101- bzr_branch: {writeOnce: true},
102- charm_store_path: {writeOnce: true},
103+ charm_store_path: {
104+ getter: function () {
105+ // charm_store_path
106+ var owner = this.get('owner');
107+ return [
108+ (owner ? '~' + owner : 'charms'),
109+ this.get('series'),
110+ (this.get('package_name') + '-' + this.get('revision')),
111+ 'json'
112+ ].join('/');
113+ },
114+ writeOnce: true
115+ },
116 config: {writeOnce: true},
117 description: {writeOnce: true},
118- full_name: {writeOnce: true},
119+ full_name: {
120+ getter: function () {
121+ // full_name
122+ var tmp = [this.get('series'), this.get('package_name')],
123+ owner = this.get('owner');
124+ if (owner) {
125+ tmp.unshift('~' + owner);
126+ }
127+ return tmp.join('/');
128+ },
129+ writeOnce: true
130+ },
131 is_subordinate: {writeOnce: true},
132 last_change: {
133 writeOnce: true,
134@@ -207,9 +248,9 @@
135 }
136 },
137 maintainer: {writeOnce: true},
138- metadata: {writeOnce: true},
139+ //metadata: {writeOnce: true},
140+ owner: {writeOnce: true},
141 package_name: {writeOnce: true},
142- owner: {writeOnce: true},
143 peers: {writeOnce: true},
144 proof: {writeOnce: true},
145 provides: {writeOnce: true},
146@@ -272,6 +313,119 @@
147 });
148 models.CharmList = CharmList;
149
150+
151+ models.BrowserCharm = Y.Base.create('browser-charm', Charm, [], {
152+
153+ }, {
154+ ATTRS: {
155+ id: {
156+ writeOnce: true,
157+ validator: function(val) {
158+ return Y.Lang.isString(val) && !!charmIdRe.exec(val);
159+ }
160+ },
161+ bzr_branch: {writeOnce: true},
162+ categories: {
163+ value: [],
164+ writeOnce: true
165+ },
166+ changelog: {
167+ value: {},
168+ writeOnce: true
169+ },
170+ charm_store_path: {writeOnce: true},
171+ code_source: {writeOnce: true},
172+ date_created: {writeOnce: true},
173+ description: {writeOnce: true},
174+ files: {
175+ value: {},
176+ writeOnce: true
177+ },
178+ full_name: {
179+ getter: function () {
180+ // full_name
181+ var tmp = [this.get('series'), this.get('package_name')],
182+ owner = this.get('owner');
183+ if (owner) {
184+ tmp.unshift('~' + owner);
185+ }
186+ return tmp.join('/');
187+ },
188+ writeOnce: true
189+ },
190+ is_approved: {writeOnce: true},
191+ is_new: {writeOnce: true},
192+ is_popular:{writeOnce: true},
193+ is_subordinate: {writeOnce: true},
194+ last_change: {
195+ writeOnce: true,
196+
197+ /**
198+ * Normalize created value from float to date object.
199+ *
200+ * @method last_change.writeOnce.setter
201+ */
202+ setter: function(val) {
203+ if (val && val.created) {
204+ // Mutating in place should be fine since this should only
205+ // come from loading over the wire.
206+ val.created = new Date(val.created * 1000);
207+ }
208+ return val;
209+ }
210+ },
211+ maintainer: {writeOnce: true},
212+ //metadata: {writeOnce: true},
213+ name: {writeOnce: true},
214+ config: {writeOnce: true},
215+ owner: {writeOnce: true},
216+ peers: {writeOnce: true},
217+ proof: {writeOnce: true},
218+ provides: {writeOnce: true},
219+ rating_numerator: {writeOnce: true},
220+ rating_denominator: {writeOnce: true},
221+ recent_downloads: {writeOnce: true},
222+ relations: {writeOnce: true},
223+ requires: {writeOnce: true},
224+ revision: {
225+ writeOnce: true,
226+
227+ /**
228+ * Parse the revision number out of a string.
229+ *
230+ * @method revision.writeOnce.setter
231+ */
232+ setter: function(val) {
233+ if (Y.Lang.isValue(val)) {
234+ val = parseInt(val, 10);
235+ }
236+ return val;
237+ }
238+ },
239+ scheme: {
240+ value: 'cs',
241+ writeOnce: true,
242+
243+ /**
244+ * If no value is given, "cs" is used as the default.
245+ *
246+ * @method scheme.writeOnce.setter
247+ */
248+ setter: function(val) {
249+ if (!Y.Lang.isValue(val)) {
250+ val = 'cs';
251+ }
252+ return val;
253+ }
254+ },
255+ series: {writeOnce: true},
256+ summary: {writeOnce: true},
257+ tested_providers: {writeOnce: true},
258+ url: {writeOnce: true}
259+ }
260+ });
261+
262+
263 }, '0.1.0', {
264 requires: [
265 'model',
266@@ -279,3 +433,5 @@
267 'juju-charm-id'
268 ]
269 });
270+
271+// vim: set tabstop=2:shiftwidth=2
272
273=== modified file 'app/store/charm.js'
274--- app/store/charm.js 2013-03-11 13:56:47 +0000
275+++ app/store/charm.js 2013-03-20 14:43:53 +0000
276@@ -1,3 +1,4 @@
277+/*global YUI: false, escape: false*/
278 'use strict';
279
280 /**
281@@ -9,14 +10,18 @@
282
283 YUI.add('juju-charm-store', function(Y) {
284
285+ var ns = Y.namespace('juju');
286+
287 /**
288 * The CharmStore class.
289 *
290 * @class CharmStore
291+ * @extends {Y.Base}
292+ *
293 */
294 var CharmStore = Y.Base.create('charm', Y.Base, [], {
295
296- loadByPath: function(path, options) {
297+ charm: function(path, options) {
298 this.get('datasource').sendRequest({
299 request: path,
300 callback: {
301@@ -131,12 +136,98 @@
302 }
303 }
304 });
305- Y.namespace('juju').CharmStore = CharmStore;
306-
307-}, '0.1.0', {
308+ ns.CharmStore = CharmStore;
309+
310+
311+ /**
312+ * Provides hook up to the Charmworld Api v0
313+ *
314+ * @class Charmworld0
315+ * @extends {Y.Base}
316+ *
317+ */
318+ ns.Charmworld0 = Y.Base.create('browser-api-0', Y.Base, [], {
319+ _api_path: 'api/0/',
320+
321+ _endpoints: {
322+ 'charm': 'charm/{id}/',
323+ 'find': 'charms/',
324+ 'qa': 'charm/{id}/qa/',
325+ 'file': 'charm/{id}/files/{path}/',
326+ },
327+
328+ charm: function(charmid, options) {
329+ var path = Y.sub(this._endpoints, {id: charmid});
330+
331+ // path is known
332+ this.get('datasource').sendRequest({
333+ request: path,
334+ callback: {
335+ success: function(io_request) {
336+ debugger;
337+ options.success(
338+ Y.JSON.parse(io_request.response.results[0].responseText));
339+ },
340+ failure: options.failure
341+ }
342+ });
343+ },
344+
345+ find: function() {
346+
347+ },
348+
349+ initializer: function(cfg) {
350+
351+ },
352+
353+ qa: function() {
354+
355+ },
356+
357+ file: function() {
358+
359+ }
360+
361+ }, {
362+ ATTRS: {
363+ /**
364+ * api_host is the host to the api server used for all calls. It auto
365+ * creates the datasource instance when set.
366+ *
367+ * @attribute api_host
368+ * @default ''
369+ * @type {String}
370+ *
371+ */
372+ api_host: {
373+ setter: function(val) {
374+ var api_endpoint = [val, this._api_path].join('/');
375+ this.set(
376+ 'datasource',
377+ new Y.DataSource.IO({ source: api_endpoint }));
378+ return val;
379+ }
380+ },
381+
382+ /**
383+ * datasource is auto set as part of the api_host ATTR.
384+ *
385+ * @attribute datasource
386+ * @default undefined
387+ * @type {Y.DataSource.IO}
388+ *
389+ */
390+ datasource: {}
391+ }
392+ });
393+
394+} , '0.1.0', {
395 requires: [
396 'juju-charm-id',
397 'datasource-io',
398 'json-parse'
399 ]
400 });
401+
402+// vim: set tabstop=2:shiftwidth=2

Subscribers

People subscribed via source and target branches