Merge upstream pull request #391 from aynik/fs-backlog-loading
Loads backlog from filesystem if logging enabled. closes #8 Conflicts: client/js/libs.min.js
This commit is contained in:
commit
2c00acc71d
|
@ -172,6 +172,7 @@ Client.prototype.connect = function(args) {
|
||||||
port: server.port,
|
port: server.port,
|
||||||
tls: !!args.tls,
|
tls: !!args.tls,
|
||||||
password: args.password,
|
password: args.password,
|
||||||
|
user: nick,
|
||||||
username: username,
|
username: username,
|
||||||
realname: realname,
|
realname: realname,
|
||||||
commands: args.commands
|
commands: args.commands
|
||||||
|
@ -252,12 +253,13 @@ Client.prototype.more = function(data) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
var chan = target.chan;
|
var chan = target.chan;
|
||||||
var count = chan.messages.length - (data.count || 0);
|
var count = chan.messages.count - (data.count || 0);
|
||||||
var messages = chan.messages.slice(Math.max(0, count - 100), count);
|
chan.messages.fetch(Math.max(0, count - 100), count, function(err, messages){
|
||||||
client.emit("more", {
|
client.emit("more", {
|
||||||
chan: chan.id,
|
chan: chan.id,
|
||||||
messages: messages
|
messages: messages
|
||||||
});
|
});
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
Client.prototype.open = function(data) {
|
Client.prototype.open = function(data) {
|
||||||
|
|
|
@ -1,10 +1,76 @@
|
||||||
var path = require("path");
|
var path = require("path");
|
||||||
|
var fs = require('fs');
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
HOME: (process.env.HOME || process.env.USERPROFILE) + "/.shout",
|
HOME: (process.env.HOME || process.env.USERPROFILE) + "/.shout",
|
||||||
getConfig: getConfig
|
getConfig: getConfig,
|
||||||
|
getLines: getLines,
|
||||||
|
countLines: countLines
|
||||||
};
|
};
|
||||||
|
|
||||||
function getConfig() {
|
function getConfig() {
|
||||||
return require(path.resolve(this.HOME) + "/config");
|
return require(path.resolve(this.HOME) + "/config");
|
||||||
};
|
};
|
||||||
|
|
||||||
|
function getLines(filename, from, to, callback) {
|
||||||
|
var stream = fs.createReadStream(filename, {
|
||||||
|
flags: 'r',
|
||||||
|
encoding: 'utf-8',
|
||||||
|
fd: null,
|
||||||
|
mode: 0666,
|
||||||
|
bufferSize: 1024
|
||||||
|
});
|
||||||
|
|
||||||
|
function endReached(){
|
||||||
|
callback(null, lines.slice(0, lines.length-1));
|
||||||
|
}
|
||||||
|
|
||||||
|
var lines = [];
|
||||||
|
var count = -1;
|
||||||
|
var last = "";
|
||||||
|
|
||||||
|
stream.on("data", function(data){
|
||||||
|
data = (last+data).split("\n");
|
||||||
|
last = data.pop();
|
||||||
|
var next = count + data.length;
|
||||||
|
var gtn = next >= from;
|
||||||
|
var gtm = next >= to;
|
||||||
|
if (gtn) lines = lines.concat(data.slice(lines.length ? 0 : from - count - 1));
|
||||||
|
if (gtm) {
|
||||||
|
stream.removeListener("end", endReached);
|
||||||
|
stream.close();
|
||||||
|
return callback(null, lines.slice(0, to - from));
|
||||||
|
}
|
||||||
|
count = next;
|
||||||
|
});
|
||||||
|
|
||||||
|
stream.on("error", function(err){
|
||||||
|
callback(err);
|
||||||
|
});
|
||||||
|
|
||||||
|
stream.on("end", endReached);
|
||||||
|
}
|
||||||
|
|
||||||
|
function countLines(filename, callback) {
|
||||||
|
var stream = fs.createReadStream(filename, {
|
||||||
|
flags: 'r',
|
||||||
|
encoding: 'utf-8',
|
||||||
|
fd: null,
|
||||||
|
mode: 0666,
|
||||||
|
bufferSize: 1024
|
||||||
|
});
|
||||||
|
|
||||||
|
var count = -1;
|
||||||
|
|
||||||
|
stream.on("data", function(data){
|
||||||
|
count += data.split("\n").length;
|
||||||
|
});
|
||||||
|
|
||||||
|
stream.on("error", function(err){
|
||||||
|
callback(err);
|
||||||
|
});
|
||||||
|
|
||||||
|
stream.on("end", function(){
|
||||||
|
callback(null, count);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
31
src/log.js
31
src/log.js
|
@ -43,3 +43,34 @@ module.exports.write = function(user, network, chan, msg) {
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
var redt = /^\[\d{4}\-\d{2}\-\d{2} (\d{2}:\d{2}:\d{2})\] /;
|
||||||
|
var rems = /^<([^>]+)> /;
|
||||||
|
var reus = /(\S*) */;
|
||||||
|
|
||||||
|
module.exports.parse = function(line){
|
||||||
|
var pmatch = line.match(redt);
|
||||||
|
var datetime = pmatch[1];
|
||||||
|
var msg = { id: 0, time: datetime, self: false };
|
||||||
|
line = line.substr(pmatch[0].length);
|
||||||
|
if (line[0] === "*") {
|
||||||
|
line = line.substr(2);
|
||||||
|
if (line[0] !== " ") {
|
||||||
|
pmatch = line.match(reus);
|
||||||
|
msg.from = pmatch[0];
|
||||||
|
line = line.substr(pmatch[0].length);
|
||||||
|
} else {
|
||||||
|
msg.from = "";
|
||||||
|
line = line.substr(1);
|
||||||
|
}
|
||||||
|
pmatch = line.match(reus);
|
||||||
|
msg.type = pmatch[0];
|
||||||
|
msg.text = line.substr(pmatch[0].length);
|
||||||
|
} else {
|
||||||
|
pmatch = line.match(rems);
|
||||||
|
msg.from = pmatch[1];
|
||||||
|
msg.type = "message";
|
||||||
|
msg.text = line.substr(pmatch[0].length);
|
||||||
|
}
|
||||||
|
return msg;
|
||||||
|
};
|
||||||
|
|
|
@ -1,4 +1,7 @@
|
||||||
|
var util = require("util");
|
||||||
var _ = require("lodash");
|
var _ = require("lodash");
|
||||||
|
var Helper = require("../helper");
|
||||||
|
var log = require("../log");
|
||||||
|
|
||||||
module.exports = Chan;
|
module.exports = Chan;
|
||||||
|
|
||||||
|
@ -8,18 +11,52 @@ Chan.Type = {
|
||||||
QUERY: "query"
|
QUERY: "query"
|
||||||
};
|
};
|
||||||
|
|
||||||
|
var MessageArray = function(chan){
|
||||||
|
Array.call(this);
|
||||||
|
this.chan = chan;
|
||||||
|
this.log = Helper.HOME + "/logs/" + this.chan.user
|
||||||
|
+ "/" + this.chan.network + "/" + this.chan.channel + ".log";
|
||||||
|
var that = this;
|
||||||
|
Helper.countLines(this.log, function(err, count){
|
||||||
|
that.count = err ? 0 : count;
|
||||||
|
});
|
||||||
|
};
|
||||||
|
util.inherits(MessageArray, Array);
|
||||||
|
|
||||||
|
MessageArray.prototype.push = function(message) {
|
||||||
|
var config = Helper.getConfig();
|
||||||
|
if (config.log === true) {
|
||||||
|
if (this.length > 50) this.splice(50);
|
||||||
|
}
|
||||||
|
Array.prototype.push.call(this, message);
|
||||||
|
this.count++;
|
||||||
|
};
|
||||||
|
|
||||||
|
MessageArray.prototype.fetch = function(from, to, callback) {
|
||||||
|
var messages = [];
|
||||||
|
if (from < this.length) messages = messages.concat(this.slice(from));
|
||||||
|
if (to <= this.length) callback(null, messages.slice(0, to));
|
||||||
|
else if (this.log) {
|
||||||
|
var linesFrom = from + messages.length;
|
||||||
|
Helper.getLines(this.log, linesFrom, to, function(err, lines){
|
||||||
|
callback(null, messages.concat(lines.map(log.parse)));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
else callback(null, messages);
|
||||||
|
};
|
||||||
|
|
||||||
var id = 0;
|
var id = 0;
|
||||||
|
|
||||||
function Chan(attr) {
|
function Chan(attr) {
|
||||||
_.merge(this, _.extend({
|
_.merge(this, _.extend({
|
||||||
id: id++,
|
id: id++,
|
||||||
messages: [],
|
|
||||||
name: "",
|
name: "",
|
||||||
topic: "",
|
topic: "",
|
||||||
type: Chan.Type.CHANNEL,
|
type: Chan.Type.CHANNEL,
|
||||||
unread: 0,
|
unread: 0,
|
||||||
users: []
|
users: []
|
||||||
}, attr));
|
}, attr));
|
||||||
|
this.messages = new MessageArray(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
Chan.prototype.sortUsers = function() {
|
Chan.prototype.sortUsers = function() {
|
||||||
|
|
|
@ -24,7 +24,10 @@ function Network(attr) {
|
||||||
this.channels.unshift(
|
this.channels.unshift(
|
||||||
new Chan({
|
new Chan({
|
||||||
name: this.name,
|
name: this.name,
|
||||||
type: Chan.Type.LOBBY
|
type: Chan.Type.LOBBY,
|
||||||
|
user: this.user,
|
||||||
|
network: this.host,
|
||||||
|
channel: this.host
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,7 +9,10 @@ module.exports = function(irc, network) {
|
||||||
var chan = _.find(network.channels, {name: data.channel});
|
var chan = _.find(network.channels, {name: data.channel});
|
||||||
if (typeof chan === "undefined") {
|
if (typeof chan === "undefined") {
|
||||||
chan = new Chan({
|
chan = new Chan({
|
||||||
name: data.channel
|
name: data.channel,
|
||||||
|
user: data.nick,
|
||||||
|
network: network.host,
|
||||||
|
channel: data.channel
|
||||||
});
|
});
|
||||||
network.channels.push(chan);
|
network.channels.push(chan);
|
||||||
client.save();
|
client.save();
|
||||||
|
|
Loading…
Reference in New Issue