Bug 753807 - Land in comm-central Instantbird's changes to chat/ - Bio 1332 - Implement /whois and /whowas commands, r=clokep,fqueze.
This commit is contained in:
Родитель
caea2ebce7
Коммит
f5dbde7463
|
@ -66,6 +66,7 @@ command.umode=%S (+|-)<new mode>: Set or unset a user mode.
|
|||
command.version=%S <nick>: Request the version of a user's client.
|
||||
command.voice=%S <nick1>[,<nick2>]*: Grant channel voice status to someone. You must be a channel operator to do this.
|
||||
command.wallops=%S <message>: If you don't know what this is, you probably can't use it (sends a command to all connected with the +w flag and all operators on the server.
|
||||
command.whois=%S <nick>: Get information on a user.
|
||||
command.whowas=%S <nick>: Get information on a user that has logged off.
|
||||
|
||||
# LOCALIZATION NOTE (message.*):
|
||||
|
@ -110,9 +111,17 @@ message.topicRemoved=The topic for %S was removed.
|
|||
message.invited=%1$S was successfully invited to %2$S.
|
||||
# %S is the nickname of the user who was summoned.
|
||||
message.summoned=%S was summoned.
|
||||
# %S is the nickname of the user whose WHOIS information follows this message.
|
||||
message.whois=WHOIS information for %S:
|
||||
# %1$S is the nickname of the (offline) user whose WHOWAS information follows this message.
|
||||
message.whowas=%1$S is offline. WHOWAS information for %1$S:
|
||||
# %1$S is the entry description (from tooltip.*), %2$S is its value.
|
||||
message.whoisEntry=\ua0\ua0\ua0\ua0%1$S: %2$S
|
||||
# %S is the nickname that is not known to the server.
|
||||
message.unknownNick=%S is an unknown nickname.
|
||||
|
||||
# LOCALIZATION NOTE (error.*):
|
||||
# These are shown as error messages in the conversation.
|
||||
# These are shown as error messages in the server tab.
|
||||
# %S is the channel name.
|
||||
error.noChannel=There is no channel: %S.
|
||||
error.tooManyChannels=Cannot join %S; you've joined too many channels.
|
||||
|
@ -121,6 +130,8 @@ error.nickCollision=Nick already in use, changing nick to %1$S [%2$S].
|
|||
error.banned=You are banned from this server.
|
||||
error.bannedSoon=You will soon be banned from this server.
|
||||
error.mode.wrongUser=You cannot change modes for other users.
|
||||
error.noSuchNick=There is no nickname or channel: %S
|
||||
error.wasNoSuchNick=There was no nickname: %S
|
||||
|
||||
# LOCALIZATION NOTE (tooltip.*):
|
||||
# These are the descriptions given in a tooltip with information received
|
||||
|
|
|
@ -106,9 +106,12 @@ function ircMessage(aData) {
|
|||
|
||||
function ircChannel(aAccount, aName, aNick) {
|
||||
this._init(aAccount, aName, aNick);
|
||||
this._observedNicks = [];
|
||||
}
|
||||
ircChannel.prototype = {
|
||||
__proto__: GenericConvChatPrototype,
|
||||
_observedNicks: [],
|
||||
|
||||
sendMsg: function(aMessage) {
|
||||
this._account.sendMessage("PRIVMSG", [this.name, aMessage]);
|
||||
|
||||
|
@ -149,6 +152,8 @@ ircChannel.prototype = {
|
|||
unInit: function() {
|
||||
this._account.removeConversation(this.name);
|
||||
GenericConvChatPrototype.unInit.call(this);
|
||||
if (this._observedNicks.length)
|
||||
Services.obs.removeObserver(this, "user-info-received");
|
||||
},
|
||||
|
||||
getNormalizedChatBuddyName: function(aNick)
|
||||
|
@ -222,6 +227,26 @@ ircChannel.prototype = {
|
|||
get topicSettable() true,
|
||||
|
||||
get normalizedName() this._account.normalize(this.name),
|
||||
|
||||
waitForBuddyInfo: function(aNick) {
|
||||
if (!this._observedNicks.length)
|
||||
Services.obs.addObserver(this, "user-info-received", false);
|
||||
this._observedNicks.push(this._account.normalize(aNick));
|
||||
},
|
||||
|
||||
observe: function(aSubject, aTopic, aData) {
|
||||
if (aTopic != "user-info-received")
|
||||
return;
|
||||
|
||||
let nickIndex = this._observedNicks.indexOf(this._account.normalize(aData));
|
||||
if (nickIndex == -1)
|
||||
return;
|
||||
this._observedNicks.splice(nickIndex, 1);
|
||||
if (!this._observedNicks.length)
|
||||
Services.obs.removeObserver(this, "user-info-received");
|
||||
this._account.writeWhois(this, aData,
|
||||
aSubject.QueryInterface(Ci.nsISimpleEnumerator));
|
||||
}
|
||||
};
|
||||
|
||||
function ircParticipant(aName, aAccount) {
|
||||
|
@ -273,9 +298,12 @@ function ircConversation(aAccount, aName) {
|
|||
this.buddy = aAccount.getBuddy(aName);
|
||||
|
||||
this._init(aAccount, aName);
|
||||
this._observedNicks = [];
|
||||
}
|
||||
ircConversation.prototype = {
|
||||
__proto__: GenericConvIMPrototype,
|
||||
_observedNicks: [],
|
||||
|
||||
sendMsg: function(aMessage) {
|
||||
this._account.sendMessage("PRIVMSG", [this.name, aMessage]);
|
||||
|
||||
|
@ -297,11 +325,33 @@ ircConversation.prototype = {
|
|||
unInit: function() {
|
||||
this._account.removeConversation(this.name);
|
||||
GenericConvIMPrototype.unInit.call(this);
|
||||
if (this._observedNicks.length)
|
||||
Services.obs.removeObserver(this, "user-info-received");
|
||||
},
|
||||
|
||||
updateNick: function(aNewNick) {
|
||||
this._name = aNewNick;
|
||||
this.notifyObservers(null, "update-conv-title");
|
||||
},
|
||||
|
||||
waitForBuddyInfo: function(aNick) {
|
||||
if (!this._observedNicks.length)
|
||||
Services.obs.addObserver(this, "user-info-received", false);
|
||||
this._observedNicks.push(this._account.normalize(aNick));
|
||||
},
|
||||
|
||||
observe: function(aSubject, aTopic, aData) {
|
||||
if (aTopic != "user-info-received")
|
||||
return;
|
||||
|
||||
let nickIndex = this._observedNicks.indexOf(this._account.normalize(aData));
|
||||
if (nickIndex == -1)
|
||||
return;
|
||||
this._observedNicks.splice(nickIndex, 1);
|
||||
if (!this._observedNicks.length)
|
||||
Services.obs.removeObserver(this, "user-info-received");
|
||||
this._account.writeWhois(this, aData,
|
||||
aSubject.QueryInterface(Ci.nsISimpleEnumerator));
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -495,8 +545,15 @@ ircAccount.prototype = {
|
|||
// Request WHOIS information on a buddy when the user requests more
|
||||
// information.
|
||||
requestBuddyInfo: function(aBuddyName) {
|
||||
this.removeBuddyInfo(aBuddyName);
|
||||
this.sendMessage("WHOIS", aBuddyName);
|
||||
},
|
||||
// Request WHOWAS information on a buddy when the user requests more
|
||||
// information.
|
||||
requestOfflineBuddyInfo: function(aBuddyName) {
|
||||
this.removeBuddyInfo(aBuddyName);
|
||||
this.sendMessage("WHOWAS", aBuddyName);
|
||||
},
|
||||
// Return an nsISimpleEnumerator of imITooltipInfo for a given nick.
|
||||
getBuddyInfo: function(aNick) {
|
||||
let nick = this.normalize(aNick);
|
||||
|
@ -506,12 +563,46 @@ ircAccount.prototype = {
|
|||
let whoisInformation = this.whoisInformation[nick];
|
||||
let tooltipInfo = [];
|
||||
for (let field in whoisInformation) {
|
||||
let value = whoisInformation[field];
|
||||
tooltipInfo.push(new TooltipInfo(_("tooltip." + field), value));
|
||||
if (field != "nick" && field != "offline") {
|
||||
let value = whoisInformation[field];
|
||||
tooltipInfo.push(new TooltipInfo(_("tooltip." + field), value));
|
||||
}
|
||||
}
|
||||
|
||||
return new nsSimpleEnumerator(tooltipInfo);
|
||||
},
|
||||
// Remove a WHOIS entry.
|
||||
removeBuddyInfo: function(aNick) {
|
||||
let nick = this.normalize(aNick);
|
||||
if (hasOwnProperty(this.whoisInformation, nick))
|
||||
delete this.whoisInformation[nick];
|
||||
},
|
||||
// Write WHOIS information to a conversation.
|
||||
writeWhois: function(aConv, aNick, aTooltipInfo) {
|
||||
let nick = this.normalize(aNick);
|
||||
// RFC 2812 errors 401 and 406 result in there being no entry for the nick.
|
||||
if (!hasOwnProperty(this.whoisInformation, nick)) {
|
||||
aConv.writeMessage(null, _("message.unknownNick", nick), {system: true});
|
||||
return;
|
||||
}
|
||||
// If the nick is offline, tell the user. In that case, it's WHOWAS info.
|
||||
let msgType = "message.whois";
|
||||
if ("offline" in this.whoisInformation[nick])
|
||||
msgType = "message.whowas";
|
||||
let msg = _(msgType, this.whoisInformation[nick]["nick"]);
|
||||
while (aTooltipInfo.hasMoreElements()) {
|
||||
let elt = aTooltipInfo.getNext().QueryInterface(Ci.prplITooltipInfo);
|
||||
switch (elt.type) {
|
||||
case Ci.prplITooltipInfo.pair:
|
||||
case Ci.prplITooltipInfo.sectionHeader:
|
||||
msg += "\n" + _("message.whoisEntry", elt.label, elt.value);
|
||||
break;
|
||||
case Ci.prplITooltipInfo.sectionBreak:
|
||||
break;
|
||||
}
|
||||
}
|
||||
aConv.writeMessage(null, msg, {system: true});
|
||||
},
|
||||
|
||||
addBuddy: function(aTag, aName) {
|
||||
let buddy = new ircAccountBuddy(this, null, aTag, aName);
|
||||
|
|
|
@ -142,6 +142,9 @@ function setWhoIs(aAccount, aMessage, aFields) {
|
|||
if (!hasOwnProperty(aAccount.whoisInformation, buddyName))
|
||||
aAccount.whoisInformation[buddyName] = {};
|
||||
|
||||
// Set non-normalized nickname field.
|
||||
aAccount.whoisInformation[buddyName]["nick"] = aMessage.params[1];
|
||||
|
||||
// Set the WHOIS fields.
|
||||
for (let field in aFields)
|
||||
aAccount.whoisInformation[buddyName][field] = aFields[field];
|
||||
|
@ -654,6 +657,7 @@ var ircBase = {
|
|||
},
|
||||
"314": function(aMessage) { // RPL_WHOWASUSER
|
||||
// <nick> <user> <host> * :<real name>
|
||||
setWhoIs(this, aMessage, {offline: true});
|
||||
let source = aMessage.params[2] + "@" + aMessage.params[3];
|
||||
return setWhoIs(this, aMessage, {realname: aMessage.params[5],
|
||||
connectedFrom: source});
|
||||
|
@ -678,11 +682,17 @@ var ircBase = {
|
|||
// <nick> :End of WHOIS list
|
||||
// We've received everything about WHOIS, tell the tooltip that is waiting
|
||||
// for this information.
|
||||
let buddyName = this.normalize(aMessage.params[1]);
|
||||
let nick = this.normalize(aMessage.params[1]);
|
||||
|
||||
// Notify the tooltip.
|
||||
Services.obs.notifyObservers(this.getBuddyInfo(buddyName),
|
||||
"user-info-received", buddyName);
|
||||
if (hasOwnProperty(this.whoisInformation, nick)) {
|
||||
Services.obs.notifyObservers(this.getBuddyInfo(nick),
|
||||
"user-info-received", nick);
|
||||
}
|
||||
else {
|
||||
// If there is no whois information stored at this point, the nick
|
||||
// is either offline or does not exist, so we run WHOWAS.
|
||||
this.requestOfflineBuddyInfo(nick);
|
||||
}
|
||||
return true;
|
||||
},
|
||||
"319": function(aMessage) { // RPL_WHOISCHANNELS
|
||||
|
@ -862,8 +872,12 @@ var ircBase = {
|
|||
},
|
||||
"369": function(aMessage) { // RPL_ENDOFWHOWAS
|
||||
// <nick> :End of WHOWAS
|
||||
// TODO
|
||||
return false;
|
||||
// We've received everything about WHOWAS, tell the tooltip that is waiting
|
||||
// for this information.
|
||||
let nick = this.normalize(aMessage.params[1]);
|
||||
Services.obs.notifyObservers(this.getBuddyInfo(nick),
|
||||
"user-info-received", nick);
|
||||
return true;
|
||||
},
|
||||
|
||||
/*
|
||||
|
@ -955,8 +969,10 @@ var ircBase = {
|
|||
// Error messages, Implement Section 5.2 of RFC 2812
|
||||
"401": function(aMessage) { // ERR_NOSUCHNICK
|
||||
// <nickname> :No such nick/channel
|
||||
// TODO Parse & display an error to the user.
|
||||
return false;
|
||||
// Can arise in response to /mode, /invite, /kill, /msg, /whois.
|
||||
// TODO Only handled in the conversation for /whois so far.
|
||||
return errorMessage(this, aMessage,
|
||||
_("error.noSuchNick", aMessage.params[1]));
|
||||
},
|
||||
"402": function(aMessage) { // ERR_NOSUCHSERVER
|
||||
// <server name> :No such server
|
||||
|
@ -980,8 +996,9 @@ var ircBase = {
|
|||
},
|
||||
"406": function(aMessage) { // ERR_WASNOSUCHNICK
|
||||
// <nickname> :There was no such nickname
|
||||
// TODO Error saying the nick never existed.
|
||||
return false;
|
||||
// Can arise in response to WHOWAS.
|
||||
return errorMessage(this, aMessage,
|
||||
_("error.wasNoSuchNick", aMessage.params[1]));
|
||||
},
|
||||
"407": function(aMessage) { // ERR_TOOMANYTARGETS
|
||||
// <target> :<error code> recipients. <abord message>
|
||||
|
|
|
@ -38,10 +38,16 @@
|
|||
// implementing the commands field before we register them.
|
||||
const EXPORTED_SYMBOLS = ["commands"];
|
||||
|
||||
Components.utils.import("resource:///modules/ircUtils.jsm");
|
||||
const {classes: Cc, interfaces: Ci, utils: Cu} = Components;
|
||||
|
||||
Cu.import("resource:///modules/ircUtils.jsm");
|
||||
Cu.import("resource:///modules/imServices.jsm");
|
||||
|
||||
// Shortcut to get the JavaScript conversation object.
|
||||
function getConv(aConv) aConv.wrappedJSObject;
|
||||
|
||||
// Shortcut to get the JavaScript account object.
|
||||
function getAccount(aConv) aConv.wrappedJSObject._account;
|
||||
function getAccount(aConv) getConv(aConv)._account;
|
||||
|
||||
// Kick a user from a channel
|
||||
// aMsg is <user> [comment]
|
||||
|
@ -94,9 +100,8 @@ function actionCommand(aMsg, aConv) {
|
|||
return false;
|
||||
|
||||
// Show the action on our conversation.
|
||||
let account = getAccount(aConv);
|
||||
account.getConversation(aConv.name)
|
||||
.writeMessage(account._nickname, "/me " + aMsg, {outgoing: true});
|
||||
getConv(aConv).writeMessage(getAccount(aConv)._nickname, "/me " + aMsg,
|
||||
{outgoing: true});
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -129,6 +134,15 @@ function ctcpCommand(aConv, aTarget, aCommand, aMsg) {
|
|||
return true;
|
||||
}
|
||||
|
||||
function whoisCommand(aMsg, aConv) {
|
||||
aMsg = aMsg.trim();
|
||||
if (!aMsg || aMsg.indexOf(" ") != -1)
|
||||
return false;
|
||||
getConv(aConv).waitForBuddyInfo(aMsg);
|
||||
getAccount(aConv).requestBuddyInfo(aMsg);
|
||||
return true;
|
||||
}
|
||||
|
||||
var commands = [
|
||||
{
|
||||
name: "action",
|
||||
|
@ -241,7 +255,7 @@ var commands = [
|
|||
name: "part",
|
||||
get helpString() _("command.part", "part"),
|
||||
run: function (aMsg, aConv) {
|
||||
aConv.wrappedJSObject.part(aMsg);
|
||||
getConv(aConv).part(aMsg);
|
||||
return true;
|
||||
}
|
||||
},
|
||||
|
@ -312,9 +326,16 @@ var commands = [
|
|||
get helpString() _("command.wallops", "wallops"),
|
||||
run: function(aMsg, aConv) simpleCommand(aConv, "WALLOPS", aMsg)
|
||||
},
|
||||
{
|
||||
name: "whois",
|
||||
get helpString() _("command.whois", "whois"),
|
||||
run: whoisCommand
|
||||
},
|
||||
{
|
||||
name: "whowas",
|
||||
get helpString() _("command.whowas", "whowas"),
|
||||
run: function(aMsg, aConv) simpleCommand(aConv, "WHOWAS", aMsg)
|
||||
// We can run whoisCommand here as that will automatically execute whowas
|
||||
// if the nick is offline (and show the nick is actually online if not).
|
||||
run: whoisCommand
|
||||
}
|
||||
];
|
||||
|
|
Загрузка…
Ссылка в новой задаче