started documenting

This commit is contained in:
hydrabolt 2015-08-16 17:48:55 +01:00
parent 9422a56d4e
commit 4773df9fc8
4 changed files with 280 additions and 45 deletions

View file

@ -379,18 +379,13 @@ Commands[ "activity" ] = {
var report = "here's a list of activity over the last " + count + " messages :\n\n";
var users = {};
for ( id in activity ) {
users[ id ] = message.channel.server.members.filter( "id", id, true );
var usernames = {};
for( id in activity ){
usernames[id] = bot.getUser(id).username;
}
activity = Object.keys( activity ).sort( function( a, b ) {
return activity[ a ] - activity[ b ]
} );
for ( id in activity ) {
report += id + " | " + activity[ id ] + " | **" + Math.round( ( activity[ id ] / count ) * 100 ) + "%**.\n";
report += usernames[id] + " | " + activity[ id ] + " | **" + Math.round( ( activity[ id ] / count ) * 100 ) + "%**.\n";
}
bot.reply( message, report, false, false );

160
index.js
View file

@ -10,6 +10,13 @@ var PMChannel = require( "./lib/PMChannel.js" ).PMChannel;
var WebSocket = require( 'ws' );
var Internal = require( "./lib/internal.js" ).Internal;
/**
* The wrapper module for the Discord Client, also provides some helpful objects.
*
* @module Discord
*/
exports;
exports.Endpoints = Endpoints;
exports.Server = Server;
exports.Message = Message;
@ -19,55 +26,156 @@ exports.List = List;
exports.Invite = Invite;
exports.PMChannel = PMChannel;
/**
* The Discord Client used to interface with the Discord API.
* @class Client
* @constructor
* @param {Object} options An object containing configurable options.
* @param {Number} [options.maxmessage=5000] The maximum amount of messages to be stored per channel.
*/
exports.Client = function( options ) {
/**
* Contains the options of the client
* @attribute options
* @type {Object}
*/
this.options = options || {};
this.options.maxmessage = 5000;
/**
* Contains the token used to authorise HTTP requests and WebSocket connection. Received when login was successful.
* @attribute token
* @readonly
* @type {String}
*/
this.token = "";
/**
* Indicates whether the client is logged in or not. Does not indicate whether the client is ready.
* @attribute loggedIn
* @readonly
* @type {Boolean}
*/
this.loggedIn = false;
/**
* The WebSocket used when receiving message and other event updates.
* @type {WebSocket}
* @attribute websocket
* @readonly
*/
this.websocket = null;
/**
* An Object containing the functions tied to events. These should be set using Client.on();
* @type {Object}
* @attribute events
*/
this.events = {};
/**
* The User of the Client class, set when the initial startup is complete.
* @attribute user
* @type {User}
* @readonly
*/
this.user = null;
/**
* Indicates whether the Client is ready and has cached all servers it as aware of.
* @type {Boolean}
* @attribute ready
* @readonly
*/
this.ready = false;
/**
* A List containing all the Servers the Client has access to.
* @attribute serverList
* @type {List}
* @readonly
*/
this.serverList = new List( "id" );
/**
* A List containing all the PMChannels the Client has access to.
* @attribute PMList
* @type {List}
* @readonly
*/
this.PMList = new List( "id" );
}
/**
* Returns a list of all servers that the Discord Client has access to.
*
* @method getServers
* @return {List} ServerList
*/
exports.Client.prototype.getServers = function() {
return this.serverList;
}
/**
* Returns a list of all servers that the Discord Client has access to.
* @method getChannels
* @return {List} Channelist
*/
exports.Client.prototype.getChannels = function() {
return this.serverList.concatSublists( "channels", "id" );
}
/**
* Returns a Server matching the given id, or false if not found. Will return false if the server is not cached or not available.
* @method getServer
* @param {String/Number} id The ID of the Server
* @return {Server} The Server matching the ID
*/
exports.Client.prototype.getServer = function( id ) {
return this.getServers().filter( "id", id, true );
}
/**
* Returns a Channel matching the given id, or false if not found. Will return false if the Channel is not cached or not available.
* @method getChannel
* @param {String/Number} id The ID of the Channel
* @return {Server} The Channel matching the ID
*/
exports.Client.prototype.getChannel = function( id ) {
return this.getChannels().filter( "id", id, true );
}
/**
* Triggers an .on() event.
* @param {String} event The event to be triggered
* @param {Array} args The arguments to be passed onto the method
* @return {Boolean} whether the event was triggered successfully.
* @private
*/
exports.Client.prototype.triggerEvent = function( event, args ) {
if ( !this.ready && event !== "raw" && event !== "disconnected" && event !== "debug" ) { //if we're not even loaded yet, don't try doing anything because it always ends badly!
return;
return false;
}
if ( this.events[ event ] ) {
this.events[ event ].apply( this, args );
return true;
} else {
return false;
}
}
/**
* Binds a function to an event
* @param {String} name The event name which the function should be bound to.
* @param {Function} fn The function that should be bound to the event.
* @method on
*/
exports.Client.prototype.on = function( name, fn ) {
this.events[ name ] = fn;
}
/**
* Unbinds a function from an event
* @param {String} name The event name which should be cleared
* @method off
*/
exports.Client.prototype.off = function( name ) {
this.events[ name ] = function() {};
}
@ -132,15 +240,29 @@ exports.Client.prototype.cacheServer = function( id, cb, members ) {
}
exports.Client.prototype.login = function( email, password ) {
/**
* Logs the Client in with the specified credentials and begins initialising it.
* @async
* @method login
* @param {String} email The Discord email.
* @param {String} password The Discord password.
* @param {Function} [callback] Called when received reply from authentication server.
* @param {Object} callback.error Set to null if there was no error logging in, otherwise is an Object that
* can be evaluated as true.
* @param {String} callback.error.reason The reason why there was an error
* @param {Object} callback.error.error The raw XHR error.
* @param {String} callback.token The token received when logging in
*/
exports.Client.prototype.login = function( email, password, callback ) {
var self = this;
callback = callback || function() {};
self.connectWebsocket();
var time = Date.now();
Internal.XHR.login( email, password, function( err, token ) {
console.log(Date.now() - time);
console.log( Date.now() - time );
if ( err ) {
self.triggerEvent( "disconnected", [ {
reason: "failed to log in",
@ -151,6 +273,7 @@ exports.Client.prototype.login = function( email, password ) {
self.token = token;
self.websocket.sendData();
self.loggedIn = true;
callback( null, token );
}
} );
@ -343,11 +466,11 @@ exports.Client.prototype.connectWebsocket = function( cb ) {
}
this.websocket.onopen = function() {
this.sendData("onopen");
this.sendData( "onopen" );
}
this.websocket.sendData = function(why){
if(this.readyState == 1 && !sentInitData && self.token){
this.websocket.sendData = function( why ) {
if ( this.readyState == 1 && !sentInitData && self.token ) {
sentInitData = true;
var connDat = {
op: 2,
@ -365,7 +488,7 @@ exports.Client.prototype.connectWebsocket = function( cb ) {
exports.Client.prototype.logout = function( callback ) {
callback = callback || function(){};
callback = callback || function() {};
var self = this;
@ -580,18 +703,18 @@ exports.Client.prototype.deleteMessage = function( message, callback ) {
Internal.XHR.deleteMessage( self.token, message.channel.id, message.id, callback );
}
exports.Client.prototype.updateMessage = function(oldMessage, newContent, callback, options){
exports.Client.prototype.updateMessage = function( oldMessage, newContent, callback, options ) {
var self = this;
var channel = oldMessage.channel;
options = options || {};
Internal.XHR.updateMessage(self.token, channel.id, oldMessage.id, {
content : newContent,
mentions : []
}, function(err, data){
if(err){
callback(err);
Internal.XHR.updateMessage( self.token, channel.id, oldMessage.id, {
content: newContent,
mentions: []
}, function( err, data ) {
if ( err ) {
callback( err );
return;
}
var msg = new Message( data, self.getChannel( data.channel_id ) );
@ -601,7 +724,7 @@ exports.Client.prototype.updateMessage = function(oldMessage, newContent, callba
}, options.selfDestruct );
}
callback( null, msg );
});
} );
}
@ -667,13 +790,6 @@ exports.Client.prototype.deleteServer = function( server, callback ) {
}
/**
UTILS
UTILS
UTILS
did I mention UTILS?
*/
exports.Client.prototype.getServers = function() {
return this.serverList;
}

View file

@ -1,9 +1,39 @@
/**
* Similar to a Java set. Contains no duplicate elements and includes filter
* functions. Discriminates between elements based on a discriminator passed
* when created. Generally "ID"
* @class List
*/
exports.List = function( discriminator, cap ) {
/**
* What to use to distringuish duplicates
* @attribute discriminator
* @type {String}
*/
this.discriminator = discriminator;
/**
* The maximum amount of elements allowed in the list.
* @default Infinity
* @attribute cap
* @type {Number}
*/
this.cap = cap || Number.MAX_SAFE_INTEGER;
/**
* The Array version of the List.
* @type {Array}
* @attribute contents
*/
this.contents = [];
}
/**
* Adds an element to the list if it isn't already there.
* @method add
* @param {Object/Array} element The element(s) to add
* @example
* List.add( obj );
* List.add( [ obj, obj, obj ] );
*/
exports.List.prototype.add = function( child ) {
var self = this;
@ -12,17 +42,17 @@ exports.List.prototype.add = function( child ) {
children = child;
for ( child of children ) {
addChild(child);
addChild( child );
}
} else {
addChild(child);
addChild( child );
}
function addChild(child){
function addChild( child ) {
if(self.length() > self.cap){
self.splice(0, 1);
if ( self.length() > self.cap ) {
self.splice( 0, 1 );
}
if ( self.filter( self.discriminator, child[ self.discriminator ] ).length === 0 )
@ -30,17 +60,28 @@ exports.List.prototype.add = function( child ) {
}
}
/**
* Returns the length of the List
* @method length
* @return {Number}
*/
exports.List.prototype.length = function() {
return this.contents.length;
}
exports.List.prototype.getIndex = function( object ){
/**
* Gets the index of an element in the List or defaults to false
* @param {Object} object The element we want to get the index of
* @return {Number/Boolean} The index if the object is in the list, or false.
* @method getIndex
*/
exports.List.prototype.getIndex = function( object ) {
var index = false;
for(elementIndex in this.contents){
var element = this.contents[elementIndex];
if( element[this.discriminator] == object[this.discriminator] ){
for ( elementIndex in this.contents ) {
var element = this.contents[ elementIndex ];
if ( element[ this.discriminator ] == object[ this.discriminator ] ) {
return elementIndex;
}
@ -50,28 +91,46 @@ exports.List.prototype.getIndex = function( object ){
}
/**
* Removes an element at the specified index
* @param {Number} index
* @method removeIndex
*/
exports.List.prototype.removeIndex = function( index ) {
this.contents.splice( index, 1 );
}
/**
* Removes an element from the list
* @param {Object} element
* @method removeElement
* @return {Boolean} whether the operation was successful or not.
*/
exports.List.prototype.removeElement = function( child ) {
for ( _element in this.contents ) {
var element = this.contents[_element];
var element = this.contents[ _element ];
if ( child[ this.discriminator ] == element[ this.discriminator ] ) {
this.removeIndex( _element, 1 );
return true;
}
}
return false;
}
exports.List.prototype.updateElement = function( child, newChild ){
/**
* Replaces an element in the list with a specified element
* @param {Object} element Element to update.
* @param {Object} newElement New Element
* @return {Boolean} whether the operation was successful or not.
*/
exports.List.prototype.updateElement = function( child, newChild ) {
for ( _element in this.contents ) {
var element = this.contents[_element];
var element = this.contents[ _element ];
if ( child[ this.discriminator ] == element[ this.discriminator ] ) {
this.contents[_element] = newChild;
this.contents[ _element ] = newChild;
return true;
}
}

View file

@ -1,15 +1,66 @@
var User = require( "./user.js" ).User;
var List = require( "./list.js" ).List;
/**
* A wrapper for Server information, contains channels and users too. Developers should not instantiate the class, instead they should
* manipulate Server objects given to them.
* @class Server
* @param {String} region The region of the server
*/
exports.Server = function( region, ownerID, name, id, members, icon, afkTimeout, afkChannelId ) {
/**
* The region of the Server
* @type {String}
* @attribute region
*/
this.region = region;
/**
* The ID of the owner of the Server (not a User!)
* @type {String}
* @attribute ownerID
*/
this.ownerID = ownerID;
/**
* The name of the Server
* @type {String}
* @attribute name
*/
this.name = name;
/**
* The ID of the Server
* @type {String}
* @attribute id
*/
this.id = id;
/**
* List containing members of the Server
* @param {List}
* @attribute members
*/
this.members = new List( "id" );
/**
* List containing channelss of the Server
* @param {List}
* @attribute channels
*/
this.channels = new List( "id" );
/**
* ID of the Icon of the Server
* @param {String}
* @attribute icon
*/
this.icon = icon;
/**
* The amount of seconds that should pass before the user is
* @type {Number}
* @attribute afkTimeout
*/
this.afkTimeout = afkTimeout;
/**
* The ID of the AFK Channel, evaluates to false if doesn't exist.
* @type {String}
* @attribute afkChannelid
*/
this.afkChannelId = afkChannelId;
for ( x in members ) {
@ -18,12 +69,22 @@ exports.Server = function( region, ownerID, name, id, members, icon, afkTimeout,
}
}
/**
* Returns a valid URL pointing towards the server's icon if it has one.
* @method getIconURL
* @return {String/Boolean} If there is an icon, a URL is returned. If not, false is returned.
*/
exports.Server.prototype.getIconURL = function(){
if(!this.icon)
return false;
return "https://discordapp.com/api/guilds/"+this.id+"/icons/"+this.icon+".jpg";
}
/**
* Returns the AFK Channel if a server has one
* @method getAFKChannel
* @return {Channel/Boolean} If there is an AFK Channel, a Channel is returned. If not, false is returned.
*/
exports.Server.prototype.getAFKChannel = function(){
if(!this.afkChannelId)
@ -33,7 +94,11 @@ exports.Server.prototype.getAFKChannel = function(){
}
/**
* Returns the #general channel of the server.
* @method getDefaultChannel
* @return {Channel} Returns the #general channel of the Server.
*/
exports.Server.prototype.getDefaultChannel = function() {
return this.channels.filter( "name", "general", true );