Mercurial > psgxs
view psgxs.js @ 26:f2e9365bc8ec
Can use differents backends for node storage. Writing directory-based backend in top of file-based backend.
author | Emmanuel Gil Peyrot <linkmauve@linkmauve.fr> |
---|---|
date | Mon, 01 Nov 2010 02:39:58 +0100 |
parents | c774f2ffb271 |
children | b2faacfefb90 |
line wrap: on
line source
#!/usr/bin/env node /* * Copyright (C) 2010 Emmanuel Gil Peyrot <linkmauve@linkmauve.fr> * * This file is part of PSĜS, a PubSub server written in JavaScript. * * PSĜS is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as * published by the Free Software Foundation, either version 3 of the * License. * * PSĜS is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with PSĜS. If not, see <http://www.gnu.org/licenses/>. */ var xmpp = require('xmpp'); var sha1 = require('sha1'); require('./iso8601'); var storage = require('./storage'); var errors = require('./errors'); var makeError = errors.makeError; var utils = require('./util'); var toBareJID = utils.toBareJID; var config = require('./configuration'); var forms = require('./forms'); var conn = new xmpp.Connection(); var notifs = require('./notifs'); notifs.setConnection(conn); var modules = require('./modules'); var service_configuration = config.service_configuration; var componentJID = config.jid; var componentPassword = config.password; conn.log = function (_, m) { console.log(m); }; function _(obj, color) { var str = require('sys').inspect(obj, false, null); if (color) console.log('\033['+c+';1m' + str + '\033[0m'); else console.log(str); }; process.addListener('uncaughtException', function (err) { console.log('\033[41;1mUncaught exception (' + err + '), this should never happen:\033[0m\n' + err.stack); }); if (typeof xmpp.StanzaBuilder.cnode != 'function' || typeof xmpp.StanzaBuilder.prototype.cnode != 'function') { xmpp.StanzaBuilder.prototype.cnode = function (stanza) { var parent = this.last_node[this.last_node.length-1]; parent.tags.push(stanza); parent.children.push(stanza); this.last_node.push(stanza); return this; }; } function onIq(stanza) { var type = stanza.getAttribute('type'); var from = stanza.getAttribute('to'); var to = stanza.getAttribute('from'); var id = stanza.getAttribute('id'); var response; if (id) response = xmpp.iq({to: to, from: from, type: 'result', id: id}); else response = xmpp.iq({to: to, from: from, type: 'result'}); var sent = false; for (var i in modules) { var module = modules[i]; if (module.type && (type != module.type)) continue; for (var j in stanza.tags) { var child = stanza.tags[j]; if (module.child && (child.name != module.child)) continue; if (module.ns && (child.attr.xmlns != module.ns)) continue; if (module.child == 'pubsub') { var child2 = child.getChild(module.pschild, child.attr.xmlns); if (child2) child = child2; if (module.pschild && (!child || module.pschild != child.name)) continue; } var toSend = module.func(response, stanza, child, to); if (toSend) { conn.send(toSend); sent = true; } } } if (!sent) conn.send(makeError(response, errors.feature_not_implemented.n)); } function onMessage(stanza) { var from = stanza.getAttribute('to'); var to = stanza.getAttribute('from'); var id = stanza.getAttribute('id'); var response; if (id) response = xmpp.message({to: to, from: from, id: id}); else response = xmpp.message({to: to, from: from}); var x = stanza.getChild('x', 'jabber:x:data'); if (x) { var form = forms.parse(x); if (form.type == 'submit' && form.fields.FORM_TYPE.value == 'subscribe_authorization') { if (form.fields.subid && form.fields.subid.value) var subID = form.fields.subid.value; if (form.fields.node && form.fields.node.value) var nodeID = form.fields.node.value; if (form.fields.subscriber_jid && form.fields.subscriber_jid.value) var jid = form.fields.subscriber_jid.value; if (form.fields.allow && form.fields.allow.value) var allow = form.fields.allow.value; var type = allow? 'subscribed': 'none'; var set = storage.subscribe(nodeID, jid, type) //if (set.subid != subID) //TODO: support the multi-subscribe feature notifs.send(jid, 'subscription', nodeID, {jid: jid, subscription: type}); } else return makeError(response, errors.feature_not_implemented.n); } else return makeError(response, errors.feature_not_implemented.n); conn.send(response) } function onPresence(stanza) { var from = stanza.getAttribute('to'); var to = stanza.getAttribute('from'); var id = stanza.getAttribute('id'); var response; if (id) response = xmpp.presence({to: to, from: from, id: id}); else response = xmpp.presence({to: to, from: from}); makeError(response, errors.feature_not_implemented.n); } conn.connect(componentJID, componentPassword, function (status, condition) { if (status == xmpp.Status.CONNECTED) { conn.addHandler(onMessage, null, 'message', null, null, null); conn.addHandler(onIq, null, 'iq', null, null, null); conn.addHandler(onPresence, null, 'presence', null, null, null); if (process.argv.length >= 3) storage.load(process.argv[2]); else storage.load(); var stdin = process.openStdin(); stdin.setEncoding('utf8'); stdin.addListener('data', storage.debug); } else conn.log(xmpp.LogLevel.DEBUG, 'New connection status: ' + status + (condition? (' ('+condition+')'): '')); });