diff backends/directory.js @ 27:a36a514e8be8

Learned that “hg addremove” can be good, sometimes.
author Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
date Mon, 01 Nov 2010 02:41:04 +0100
parents
children 7cfcd7d5796c
line wrap: on
line diff
new file mode 100644
--- /dev/null
+++ b/backends/directory.js
@@ -0,0 +1,136 @@
+/*
+ *  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 fs = require('fs');
+var backend = exports;
+
+backend.save = function(dir) {
+	if (!dir)
+		dir = 'storage';
+
+	fs.stat(dir, function(err, stats) {
+		if (err)
+			fs.mkdir(dir, 0755);
+		else if (!stats.isDirectory()) {
+			console.log('\033[1;41mThe file “' + dir + '” isn’t a directory. Exiting.\033[0m');
+			process.exit(1);
+		}
+
+		fs.readdir(dir, function(err, files) {
+			function sanitize(o) {
+				var n = {};
+				for (var i in o) {
+					if (i == 'content' || o[i].setISO8601)
+						n[i] = o[i].toString();
+					else if (o[i] instanceof Array)
+						n[i] = o[i];
+					else if (typeof o[i] == 'object')
+						n[i] = sanitize(o[i]);
+					else if (typeof o[i] == 'function')
+						;
+					else
+						n[i] = o[i];
+				}
+				return n;
+			}
+			var data = sanitize(backend.list);
+
+			var inspect = require('sys').inspect;
+
+			var toDelete = [];
+
+			for (var i in files) {
+				var nodeID = files[i];
+				if (nodeID in data) {
+					fs.writeFile(dir+'/'+nodeID+'.json', inspect(data[nodeID], false, null));
+					delete data[nodeID];
+				} else
+					toDelete.push(nodeID);
+			}
+
+			for (var nodeID in data) {
+				inspect(nodeID);
+				inspect(data[nodeID]);
+				fs.writeFile(dir+'/'+nodeID+'.json', inspect(data[nodeID], false, null));
+			}
+
+			for (var nodeID in toDelete) {
+				fs.unlink(toDelete[nodeID]);
+			}
+		});
+	});
+}
+
+backend.load = function(dir) {
+	if (!dir)
+		dir = 'storage';
+
+	fs.stat(dir, function(err, stats) {
+		if (err)
+			fs.mkdir(dir, 0755);
+		else if (!stats.isDirectory()) {
+			console.log('\033[1;41mThe file “' + dir + '” isn’t a directory. Exiting.\033[0m');
+			process.exit(1);
+		}
+
+		fs.readdir(dir, function(err, files) {
+			var xmpp = require('xmpp');
+			function parseStanza(path, content) {
+				var stanza = null;
+				var stream = new xmpp.Stream({
+					stanza: function (stanza) {
+						path[content] = stanza;
+					}
+				});
+				stream.opened = true;
+				stream.data(path[content]);
+			}
+
+			function endParsing(o) {
+				var regexp = /\d{4}-\d\d-\d\dT\d\d:\d\d:\d\dZ/;
+				for (var i in o) {
+					if (typeof o[i] == 'string' && i == 'content')
+						parseStanza(o, i);
+					else if (typeof o[i] == 'string' && regexp(o[i])) {
+						var today = new Date();
+						today.setISO8601(o[i]);
+						o[i] = today;
+					} else if (typeof o[i] == 'object')
+						endParsing(o[i]);
+				}
+				return o;
+			}
+
+			backend.list = {};
+
+			for (var i in files) {
+				var file = files[i];
+				var nodeID = file.replace(/\.json$/, '');
+
+				var data = fs.readFileSync(dir+'/'+file);
+
+				var obj = eval('('+data+')');
+				backend.list[nodeID] = endParsing(obj);
+
+				for (var j in Node.prototype)
+					backend.list[nodeID][j] = Node.prototype[j];
+			}
+		});
+	});
+}