Skip to content

Instantly share code, notes, and snippets.

@jankuca
Created August 27, 2012 19:22
Show Gist options
  • Save jankuca/3491506 to your computer and use it in GitHub Desktop.
Save jankuca/3491506 to your computer and use it in GitHub Desktop.
Controller proposal
function ApiController() {
Controller.call(this);
}
ApiController.prototype = Object.create(Controller.prototype);
ApiController.prototype.error = function (status, message) {
this.render(status, { 'error': message });
};
ApiController.prototype.render = function (status, data) {
if (typeof arguments[0] !== 'number') {
data = arguments[0];
status = 200;
}
var self = this;
var end = function () {
data['status'] = status || 200;
data['ok'] = !data['error'] && (data['status'] < 400);
self.$response.writeHead(status, self.$headers);
self.$response.write(JSON.stringify(data));
self.$response.end();
this.emit('end');
};
if (this.isReady()) {
end();
} else {
this.once('ready', end);
}
};
function BaseController(users) {
ApiController.call(this);
var current_user_id = this.$session['user_id'];
if (!current_user_id) {
return this.error(401, 'Unauthorized');
}
this.current_user = users.one(current_user_id);
this.wait(this.current_user);
}
BaseController.prototype = Object.create(ApiController.prototype);
function Delayable() {
EventEmitter.call(this);
this.queue__ = [];
var self = this;
process.nextTick(function () {
if (self.queue__.length === 0) {
self.emit('ready', self);
}
});
}
Delayable.prototype.wait = function (type, source, callback) {
if (typeof arguments[0] !== 'string') {
callback = arguments[1];
source = arguments[0];
type = 'ready';
}
var queue = this.queue__;
var queue_item = [ source, type ];
queue.push(queue_item);
var self = this;
source.once(type, function () {
var index = queue.indexOf(queue_item);
queue.splice(index, 1);
if (callback) {
callback.apply(null, arguments);
}
if (queue.length === 0) {
self.emit('ready', self);
}
});
this.emit('delay', source, type);
};
Delayable.prototype.isReady = function () {
return (this.queue__.length === 0);
};
var app = framework.createApplication(__dirname + '/app');
app.routes = {
'/api': {
'GET /notebooks': 'api/notebook.index',
'POST /notebooks': 'PUT /notebooks/{@id}',
'PUT /notebooks/{id}': 'api/notebook.createNotebook',
'GET /notebooks/{id}': 'api/notebook.showNotebook',
'POST /notebooks/{id}': 'api/notebook.updateNotebook'
}
};
app.run();
function NotebookController(notebooks, users) {
BaseController.call(this, users);
this.$notebooks = notebooks;
this.$users = users;
}
NotebookController.prototype = Object.create(BaseController.prototype);
NotebookController.prototype.listNotebooks = function () {
var current_user = this.current_user;
var notebooks = this.$notebooks.all(current_user['notebooks']);
this.wait(notebooks);
this.render({ 'items': notebooks });
};
NotebookController.prototype.createNotebook = function (id) {
var values = this.$request.body;
var current_user = this.current_user;
var self = this;
var notebook = this.$notebooks.one(id, []);
notebook.on('ready', function () {
if (current_user['notebooks'].contains(id)) {
return self.updateNotebook(id);
}
return self.error(400, 'There is already a notebook with this ID.');
});
notebook.on('empty', function () {
notebook['title'] = values['title'];
notebook['created_at'] = new Date();
notebook['updated_at'] = new Date();
self.$notebooks.save(notebook, function () {
current_user['notebooks'].push(notebook.id);
self.$users.save(current_user);
self.wait(current_user);
self.wait(notebook);
self.render({ 'result': notebook });
});
});
};
NotebookController.prototype.showNotebook = function (id) {
var current_user = this.current_user;
if (!current_user['notebooks'].contains(id)) {
this.error(403, 'You are not allowed to access this notebook.');
}
var self = this;
var notebook = this.$notebooks.one(id);
notebook.on('ready', function () {
self.wait(notebook);
self.render({ 'result': notebook });
});
notebook.on('empty', function () {
self.error(404, 'Notebook not found');
});
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment