diff --git a/index.js b/index.js index 0ab6580db..7c1c1fc0a 100644 --- a/index.js +++ b/index.js @@ -4,6 +4,7 @@ var Server = require("./lib/server.js").Server; var Message = require("./lib/message.js").Message; var User = require("./lib/user.js").User; var Channel = require("./lib/channel.js").Channel; +var List = require("./lib/list.js").List; var WebSocket = require('ws'); exports.Client = function(options) { @@ -14,7 +15,8 @@ exports.Client = function(options) { this.websocket = null; this.events = {}; this.user = null; - this.channelCache = {}; + + this.serverList = new List("id"); } @@ -36,22 +38,35 @@ exports.Client.prototype.off = function(name) { this.events[name] = function() {}; } -exports.Client.prototype.cacheChannel = function(id, cb) { +exports.Client.prototype.cacheServer = function(id, cb, members) { - if (this.channelCache[id]) { - cb(this.channelCache[id]); + if ( this.serverList.filter("id", id).length > 0 ) { return; } var self = this; request - .get(Endpoints.CHANNELS + "/" + id) + .get(Endpoints.SERVERS + "/" + id) .set("authorization", this.token) .end(function(err, res) { var dat = res.body; - self.channelCache[id] = new Channel(dat.name, dat.guild_id, dat.type, dat.id, dat.is_private); - cb(self.channelCache[id]); + var server = new Server(dat.region, dat.owner_id, dat.name, dat.roles[0].id, members || dat.members); + + request + .get(Endpoints.SERVERS + "/" + id + "/channels") + .set("authorization", self.token) + .end(function(err, res){ + + var channelList = res.body; + for(channel of channelList){ + server.channels.add( new Channel(channel, server) ); + } + + self.serverList.add(server); + + cb(server); + }); }); } @@ -107,24 +122,28 @@ exports.Client.prototype.connectWebsocket = function(cb) { var _servers = data.guilds, servers = []; + + var cached = 0, toCache = _servers.length; + for (x in _servers) { _server = _servers[x]; - servers.push(new Server(_server.region, _server.owner_id, _server.name, _server.roles[0].id, _server.members)); + client.cacheServer(_server.roles[0].id, function(server) { + cached++; + if(cached >= toCache){ + client.triggerEvent("ready"); + } + }, _server.members); } - client.servers = servers; - client.user = new User(data.user.username, data.user.id, data.user.discriminator, data.user.avatar); - - client.triggerEvent("ready"); } else if (dat.t === "MESSAGE_CREATE") { var data = dat.d; - client.cacheChannel(data.channel_id, function(channel) { - var message = new Message(data.timestamp, data.author, data.content, channel, data.id, data.mentions); - client.triggerEvent("message", [message]); - }); + var channel = client.channelFromId(data.channel_id); + + var message = new Message(data, channel); + client.triggerEvent("message", [message]); } break; @@ -195,23 +214,83 @@ exports.Client.prototype.createServer = function(details, cb) { } -exports.Client.prototype.sendMessage = function(channelId, message, _mentions){ +exports.Client.prototype.sendMessage = function(channel, message, cb, _mentions) { - for(mention in _mentions){ + var cb = cb || function(){}; + + for (mention in _mentions) { _mentions[mention] = _mentions[mention].id; } var client = this; var details = { - content : message, - mentions : _mentions || [] + content: message.substring(0,2000), + mentions: _mentions || [] }; request - .post(Endpoints.CHANNELS + "/" + channelId.id + "/messages") + .post(Endpoints.CHANNELS + "/" + channel.id + "/messages") .set("authorization", client.token) .send(details) - .end(function(err, res){ + .end(function(err, res) { + cb(new Message(res.body, client.channelFromId(res.body.channel_id))); + }); +} + +exports.Client.prototype.deleteMessage = function(message) { + + var client = this; + + request + .del(Endpoints.CHANNELS + "/" + message.channel.id + "/messages/" + message.id) + .set("authorization", client.token) + .end(function(err, res) { }); } + + +exports.Client.prototype.logFile = function(name, url){ + + var fs = require("fs"); + + request + .get(url) + .set("authorization", this.token) + .end(function(err, res){ + fs.writeFile("./log/"+name+".json", JSON.stringify(res.body, null, "\t"), function(err) { + if (err) { + return console.log(err); + } + }); + }); +} + +exports.Client.prototype.channelFromId = function(id){ + var channelList = this.serverList.concatSublists("channels", "id"); + var channel = channelList.filter("id", id, true); + + return channel; +} + +exports.Client.prototype.getChannelLogs = function(channel, amount, cb){ + + amount = amount || 0; + var client = this; + + request + .get(Endpoints.CHANNELS + "/" + channel.id + "/messages?limit="+amount) + .set("authorization", client.token) + .end(function(err, res){ + + var datList = new List("id"); + + for(item of res.body){ + datList.add( new Message(item, channel) ); + } + + cb(datList); + + }); + +} diff --git a/lib/channel.js b/lib/channel.js index dbd03fbdc..d9cc555b8 100644 --- a/lib/channel.js +++ b/lib/channel.js @@ -1,7 +1,16 @@ -exports.Channel = function(name, serverId, type, id, isPrivate){ +exports.Channel = function(name, server, type, id, isPrivate){ + + if(!type){ //there's no second argument + var channel = name; + name = channel.name; + server = server; + type = channel.type; + id = channel.id; + isPrivate = channel.is_private; + } this.name = name; - this.serverId = serverId; + this.server = server; this.type = type; this.id = id; this.isPrivate = isPrivate; @@ -9,11 +18,9 @@ exports.Channel = function(name, serverId, type, id, isPrivate){ } exports.Channel.equals = function(otherChannel){ - if(otherChannel.id === this.id){ return true; } else { return false; } - } diff --git a/lib/list.js b/lib/list.js new file mode 100644 index 000000000..651e14dc6 --- /dev/null +++ b/lib/list.js @@ -0,0 +1,74 @@ +exports.List = function(discriminator) { + this.discriminator = discriminator; + this.contents = []; +} + +exports.List.prototype.add = function(child){ + if(child.constructor === Array){ + + children = child; + for(child of children){ + if( this.filter( this.discriminator, child[this.discriminator] ).length === 0 ) + this.contents.push(child); + } + + }else{ + if( this.filter( this.discriminator, child[this.discriminator] ).length === 0 ) + this.contents.push(child); + } +} + +exports.List.prototype.length = function(){ + return this.contents.length; +} + +exports.List.prototype.removeIndex = function(index){ + this.contents.splice(index, 1); +} + +exports.List.prototype.removeChild = function(child){ + + var index = this.contents.indexOf(child); + + if( index === -1 ){ + return false; + } + + this.removeIndex(index); + +} + +exports.List.prototype.concatSublists = function(whereList, discriminator){ + //this is meant to look at the contents, and assuming the contents are all lists, concatenate their values. + + var concatList = new exports.List(discriminator); + + for(item of this.contents){ + var itemList = item[whereList]; + concatList.add(itemList.contents); + } + + return concatList; +} + +exports.List.prototype.filter = function(key, value, onlyOne) { + + var results = []; + + for (index in this.contents) { + var child = this.contents[index]; + if (child[key] == value) { + if (onlyOne) { + return child; + } else { + results.push(child); + } + } + } + + if(onlyOne){ + return false; + } + + return results; +} diff --git a/lib/message.js b/lib/message.js index 3417aa7fc..1e1841066 100644 --- a/lib/message.js +++ b/lib/message.js @@ -1,12 +1,23 @@ var User = require("./user.js").User; exports.Message = function(time, author, content, channel, id, mentions){ + + if(!content){ + message = time; + channel = author; + time = message.timestamp; + author = message.author; + content = message.content; + id = message.id; + mentions = message.mentions; + } + this.time = Date.parse(time); - this.author = new User(author.username, author.id, author.discriminator, author.avatar); + this.author = new User(author); this.content = content.replace(/<[^>]*>/g, "").replace(/\s+/g, ' ').trim(); this.channel = channel; this.id = id; - this.mentions = []; + this.mentions = mentions || []; for(x in mentions){ var _mention = mentions[x]; this.mentions.push( new User(_mention.username, _mention.id, _mention.discriminator, _mention.avatar) ); diff --git a/lib/server.js b/lib/server.js index dfea014dc..9bd438a17 100644 --- a/lib/server.js +++ b/lib/server.js @@ -1,4 +1,5 @@ var User = require("./user.js").User; +var List = require("./list.js").List; exports.Server = function(region, ownerID, name, id, members){ @@ -6,10 +7,12 @@ exports.Server = function(region, ownerID, name, id, members){ this.ownerID = ownerID; this.name = name; this.id = id; - this.members = []; + this.members = new List("id"); + this.channels = new List("id"); + for(x in members){ - var _member = members[x].user; - this.members.push( new User(_member.username, _member.id, _member.discriminator, _member.avatar) ); + var member = members[x].user; + this.members.add( new User(member) ); } } diff --git a/lib/user.js b/lib/user.js index 59e4fe6a3..a53a276b7 100644 --- a/lib/user.js +++ b/lib/user.js @@ -1,4 +1,13 @@ exports.User = function(username, id, discriminator, avatar){ + + if(!id){ //there's no second argument + var user = username; + username = user.username; + id = user.id; + discriminator = user.discriminator; + avatar = user.avatar; + } + this.username = username; this.discriminator = discriminator; this.id = id;