From d55c9c19aba323053fc681c003170c980ddea633 Mon Sep 17 00:00:00 2001 From: tpltnt Date: Fri, 14 Feb 2014 12:06:09 +0100 Subject: [PATCH 01/11] package description added --- irc.go | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/irc.go b/irc.go index a123c69..1e5bb26 100644 --- a/irc.go +++ b/irc.go @@ -2,6 +2,13 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. +/* +This package provides an event based IRC client library. It allows to +register callbacks for the events you need to handle. Its features +include handling standard CTCP, reconnecting on errors and detecting +stones servers. +*/ + package irc import ( From 7f0d4b4a6d43b37d7423a0f65910f1b019cbc610 Mon Sep 17 00:00:00 2001 From: tpltnt Date: Fri, 14 Feb 2014 14:29:56 +0100 Subject: [PATCH 02/11] method doc started --- irc.go | 27 ++++++++++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/irc.go b/irc.go index 1e5bb26..ed28c89 100644 --- a/irc.go +++ b/irc.go @@ -175,12 +175,14 @@ func (irc *Connection) Loop() { } } +// Quit the current connection and disconnect from the server func (irc *Connection) Quit() { irc.SendRaw("QUIT") irc.stopped = true irc.Disconnect() } +// Use the connection to join a given channel func (irc *Connection) Join(channel string) { irc.pwrite <- fmt.Sprintf("JOIN %s\r\n", channel) } @@ -189,6 +191,8 @@ func (irc *Connection) Part(channel string) { irc.pwrite <- fmt.Sprintf("PART %s\r\n", channel) } +// Notify a user. This is simial to Privmsg but must not receive replies. +// RFC 1459 details: https://tools.ietf.org/html/rfc1459#section-4.4.2 func (irc *Connection) Notice(target, message string) { irc.pwrite <- fmt.Sprintf("NOTICE %s :%s\r\n", target, message) } @@ -218,18 +222,29 @@ func (irc *Connection) Nick(n string) { irc.SendRawf("NICK %s", n) } + +// Determine nick currently used with the connection. func (irc *Connection) GetNick() string { return irc.nickcurrent } + +// Query information about a particular nick. +// RFC 1459: https://tools.ietf.org/html/rfc1459#section-4.5.2 func (irc *Connection) Whois(nick string) { irc.SendRawf("WHOIS %s", nick) } + +// Query information about a given nick in the server. +// RFC 1459 details: https://tools.ietf.org/html/rfc1459#section-4.5.1 func (irc *Connection) Who(nick string) { irc.SendRawf("WHO %s", nick) } + +// Set different modes for a target (channel or nick). +// RFC 1459 details: https://tools.ietf.org/html/rfc1459#section-4.2.3 func (irc *Connection) Mode(target string, modestring ...string) { if len(modestring) > 0 { mode := strings.Join(modestring, " ") @@ -239,7 +254,8 @@ func (irc *Connection) Mode(target string, modestring ...string) { irc.SendRawf("MODE %s", target) } -// Sends all buffered messages (if possible), + +// A disconnect sends all buffered messages (if possible), // stops all goroutines and then closes the socket. func (irc *Connection) Disconnect() { irc.endping <- true @@ -260,10 +276,16 @@ func (irc *Connection) Disconnect() { irc.Error <- errors.New("Disconnect Called") } + +// Reconnect to a server using the current connection. func (irc *Connection) Reconnect() error { return irc.Connect(irc.server) } + +// Connect to a given server using the current connection configuration. +// This function also takes care of identification if a password is provided. +// RFC 1459 details: https://tools.ietf.org/html/rfc1459#section-4.1 func (irc *Connection) Connect(server string) error { irc.server = server irc.stopped = false @@ -297,6 +319,9 @@ func (irc *Connection) Connect(server string) error { return nil } + +// Create a connection with the (publicly visible) nickname and username. +// The nickname is later used to address the user. func IRC(nick, user string) *Connection { irc := &Connection{ nick: nick, From c000e87deea7219ad37ad91f505ece831b209a76 Mon Sep 17 00:00:00 2001 From: tpltnt Date: Fri, 14 Feb 2014 14:51:57 +0100 Subject: [PATCH 03/11] docs done --- irc.go | 43 +++++++++++++++++++++++++++++++++++++------ 1 file changed, 37 insertions(+), 6 deletions(-) diff --git a/irc.go b/irc.go index ed28c89..6c99925 100644 --- a/irc.go +++ b/irc.go @@ -27,6 +27,8 @@ const ( VERSION = "go-ircevent v2.1" ) + +// Read data from a connection. To be used as a goroutine. func (irc *Connection) readLoop() { br := bufio.NewReaderSize(irc.socket, 512) @@ -92,6 +94,8 @@ func (irc *Connection) readLoop() { irc.readerExit <- true } + +// Loop to write to a connection. To be used as a goroutine. func (irc *Connection) writeLoop() { for { select { @@ -128,7 +132,9 @@ func (irc *Connection) writeLoop() { irc.writerExit <- true } -//Pings the server if we have not received any messages for 5 minutes + +// Pings the server if we have not received any messages for 5 minutes +// to keep the connection alive. To be used as a goroutine. func (irc *Connection) pingLoop() { ticker := time.NewTicker(1 * time.Minute) // Tick every minute for monitoring ticker2 := time.NewTicker(irc.PingFreq) // Tick at the ping frequency. @@ -156,6 +162,8 @@ func (irc *Connection) pingLoop() { } } + +// Main loop to control the connection. func (irc *Connection) Loop() { for !irc.stopped { err := <-irc.Error @@ -175,48 +183,71 @@ func (irc *Connection) Loop() { } } + // Quit the current connection and disconnect from the server +// RFC 1459 details: https://tools.ietf.org/html/rfc1459#section-4.1.6 func (irc *Connection) Quit() { irc.SendRaw("QUIT") irc.stopped = true irc.Disconnect() } -// Use the connection to join a given channel + +// Use the connection to join a given channel. +// RFC 1459 details: https://tools.ietf.org/html/rfc1459#section-4.2.1 func (irc *Connection) Join(channel string) { irc.pwrite <- fmt.Sprintf("JOIN %s\r\n", channel) } + +// Leave a given channel. +// RFC 1459 details: https://tools.ietf.org/html/rfc1459#section-4.2.2 func (irc *Connection) Part(channel string) { irc.pwrite <- fmt.Sprintf("PART %s\r\n", channel) } -// Notify a user. This is simial to Privmsg but must not receive replies. + +// Send a notification to a nickname. This is similar to Privmsg but must not receive replies. // RFC 1459 details: https://tools.ietf.org/html/rfc1459#section-4.4.2 func (irc *Connection) Notice(target, message string) { irc.pwrite <- fmt.Sprintf("NOTICE %s :%s\r\n", target, message) } + +// Send a formated notification to a nickname. +// RFC 1459 details: https://tools.ietf.org/html/rfc1459#section-4.4.2 func (irc *Connection) Noticef(target, format string, a ...interface{}) { irc.Notice(target, fmt.Sprintf(format, a...)) } + +// Send (private) message to a target (channel or nickname). +// RFC 1459 details: https://tools.ietf.org/html/rfc1459#section-4.4.1 func (irc *Connection) Privmsg(target, message string) { irc.pwrite <- fmt.Sprintf("PRIVMSG %s :%s\r\n", target, message) } + +// Send formated string to specified target (channel or nickname). func (irc *Connection) Privmsgf(target, format string, a ...interface{}) { irc.Privmsg(target, fmt.Sprintf(format, a...)) } + +// Send raw string. func (irc *Connection) SendRaw(message string) { irc.pwrite <- message + "\r\n" } + +// Send raw formated string. func (irc *Connection) SendRawf(format string, a ...interface{}) { irc.SendRaw(fmt.Sprintf(format, a...)) } + +// Set (new) nickname. +// RFC 1459 details: https://tools.ietf.org/html/rfc1459#section-4.1.2 func (irc *Connection) Nick(n string) { irc.nick = n irc.SendRawf("NICK %s", n) @@ -229,21 +260,21 @@ func (irc *Connection) GetNick() string { } -// Query information about a particular nick. +// Query information about a particular nickname. // RFC 1459: https://tools.ietf.org/html/rfc1459#section-4.5.2 func (irc *Connection) Whois(nick string) { irc.SendRawf("WHOIS %s", nick) } -// Query information about a given nick in the server. +// Query information about a given nickname in the server. // RFC 1459 details: https://tools.ietf.org/html/rfc1459#section-4.5.1 func (irc *Connection) Who(nick string) { irc.SendRawf("WHO %s", nick) } -// Set different modes for a target (channel or nick). +// Set different modes for a target (channel or nickname). // RFC 1459 details: https://tools.ietf.org/html/rfc1459#section-4.2.3 func (irc *Connection) Mode(target string, modestring ...string) { if len(modestring) > 0 { From 5baf7671c652fe8335a3eaf57a23faf21fe8c2f9 Mon Sep 17 00:00:00 2001 From: tpltnt Date: Fri, 14 Feb 2014 15:03:52 +0100 Subject: [PATCH 04/11] IRC RFCs added --- irc.go | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/irc.go b/irc.go index 6c99925..5e8455d 100644 --- a/irc.go +++ b/irc.go @@ -7,6 +7,12 @@ This package provides an event based IRC client library. It allows to register callbacks for the events you need to handle. Its features include handling standard CTCP, reconnecting on errors and detecting stones servers. +Details of the IRC protocol can be found in the following RFCs: +https://tools.ietf.org/html/rfc1459 +https://tools.ietf.org/html/rfc2810 +https://tools.ietf.org/html/rfc2811 +https://tools.ietf.org/html/rfc2812 +https://tools.ietf.org/html/rfc2813 */ package irc From eef65b116e2ff6483169b218552aaad8f85cedbd Mon Sep 17 00:00:00 2001 From: tpltnt Date: Fri, 14 Feb 2014 15:40:25 +0100 Subject: [PATCH 05/11] some doc on structs --- irc_callback.go | 1 + irc_struct.go | 5 ++++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/irc_callback.go b/irc_callback.go index cee0e54..58ecbd7 100644 --- a/irc_callback.go +++ b/irc_callback.go @@ -10,6 +10,7 @@ import ( "time" ) + func (irc *Connection) AddCallback(eventcode string, callback func(*Event)) string { eventcode = strings.ToUpper(eventcode) diff --git a/irc_struct.go b/irc_struct.go index 57a4443..de05e83 100644 --- a/irc_struct.go +++ b/irc_struct.go @@ -43,6 +43,8 @@ type Connection struct { stopped bool } + +// A struct to represent an event. type Event struct { Code string Raw string @@ -53,7 +55,8 @@ type Event struct { Arguments []string } -// Convenience func to get the last arg, now that the Message field is gone + +// Extract the last message from an Event. This function eventually returns an empty string. func (e *Event) Message() string { if len(e.Arguments) == 0 { return "" From 4a8fffa82835abb0679c13878d44a9870b5b06c7 Mon Sep 17 00:00:00 2001 From: tpltnt Date: Fri, 14 Feb 2014 16:12:16 +0100 Subject: [PATCH 06/11] some doc on callback management --- irc_callback.go | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/irc_callback.go b/irc_callback.go index 58ecbd7..8453d2d 100644 --- a/irc_callback.go +++ b/irc_callback.go @@ -11,6 +11,19 @@ import ( ) +// Register a callback to a connection and event code. A callback is a function +// which takes only an Event pointer as parameter. Valid event codes are: +// 001 - welcoming on the IRC network +// 437 - if nickname or channel are currently not available +// 433 - if nickname is currently in use +// CTCP_CLIENTINFO +// CTCP_PING +// CTCP_TIME +// CTCP_USERINFO +// CTCP_VERSION +// PING - if PING is received +// PONG - if PONG is received +// NICK - if nickname (in connection) matches current message func (irc *Connection) AddCallback(eventcode string, callback func(*Event)) string { eventcode = strings.ToUpper(eventcode) @@ -41,6 +54,9 @@ func (irc *Connection) RemoveCallback(eventcode string, i string) bool { return false } + +// Remove all callbacks from a given event code. It returns true +// if given event code is found and cleared. func (irc *Connection) ClearCallback(eventcode string) bool { eventcode = strings.ToUpper(eventcode) @@ -66,6 +82,8 @@ func (irc *Connection) ReplaceCallback(eventcode string, i string, callback func irc.Log.Printf("Event not found. Use AddCallBack\n") } + +// Execute all callbacks associated with a given event. func (irc *Connection) RunCallbacks(event *Event) { msg := event.Message() if event.Code == "PRIVMSG" && len(msg) > 0 && msg[0] == '\x01' { From 7c96d05d11d777cd757bbace5554ca114ad7cf8c Mon Sep 17 00:00:00 2001 From: tpltnt Date: Fri, 14 Feb 2014 16:13:17 +0100 Subject: [PATCH 07/11] CTCP spec linked --- irc.go | 1 + 1 file changed, 1 insertion(+) diff --git a/irc.go b/irc.go index 5e8455d..4e13886 100644 --- a/irc.go +++ b/irc.go @@ -13,6 +13,7 @@ https://tools.ietf.org/html/rfc2810 https://tools.ietf.org/html/rfc2811 https://tools.ietf.org/html/rfc2812 https://tools.ietf.org/html/rfc2813 +The details of the client-to-client protocol (CTCP) can be found here: http://www.irchelp.org/irchelp/rfc/ctcpspec.html */ package irc From 735d2f0040a3641c2d2a77993618a0d73c14ee5d Mon Sep 17 00:00:00 2001 From: tpltnt Date: Fri, 14 Feb 2014 16:30:09 +0100 Subject: [PATCH 08/11] more doc on callback management --- irc_callback.go | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/irc_callback.go b/irc_callback.go index 8453d2d..b90ecec 100644 --- a/irc_callback.go +++ b/irc_callback.go @@ -24,6 +24,7 @@ import ( // PING - if PING is received // PONG - if PONG is received // NICK - if nickname (in connection) matches current message +// This function returns the ID of the registered callback for later management. func (irc *Connection) AddCallback(eventcode string, callback func(*Event)) string { eventcode = strings.ToUpper(eventcode) @@ -38,6 +39,9 @@ func (irc *Connection) AddCallback(eventcode string, callback func(*Event)) stri return id } + +// Remove callback i (ID) from the given event code. This functions returns +// true upon success, false if any error occurs. func (irc *Connection) RemoveCallback(eventcode string, i string) bool { eventcode = strings.ToUpper(eventcode) @@ -69,6 +73,8 @@ func (irc *Connection) ClearCallback(eventcode string) bool { return false } + +// Replace callback i (ID) associated with a given event code with a new callback function. func (irc *Connection) ReplaceCallback(eventcode string, i string, callback func(*Event)) { eventcode = strings.ToUpper(eventcode) @@ -138,6 +144,8 @@ func (irc *Connection) RunCallbacks(event *Event) { } } + +// Set up some initial callbacks to handle the IRC/CTCP protocol. func (irc *Connection) setupCallbacks() { irc.events = make(map[string]map[string]func(*Event)) From 8dfda9ca4fe3d009820aba1390cec45d63442043 Mon Sep 17 00:00:00 2001 From: tpltnt Date: Fri, 14 Feb 2014 16:41:58 +0100 Subject: [PATCH 09/11] event code clarification --- irc_callback.go | 16 +++------------- 1 file changed, 3 insertions(+), 13 deletions(-) diff --git a/irc_callback.go b/irc_callback.go index b90ecec..deb16ee 100644 --- a/irc_callback.go +++ b/irc_callback.go @@ -12,19 +12,9 @@ import ( // Register a callback to a connection and event code. A callback is a function -// which takes only an Event pointer as parameter. Valid event codes are: -// 001 - welcoming on the IRC network -// 437 - if nickname or channel are currently not available -// 433 - if nickname is currently in use -// CTCP_CLIENTINFO -// CTCP_PING -// CTCP_TIME -// CTCP_USERINFO -// CTCP_VERSION -// PING - if PING is received -// PONG - if PONG is received -// NICK - if nickname (in connection) matches current message -// This function returns the ID of the registered callback for later management. +// which takes only an Event pointer as parameter. Valid event codes are all +// IRC/CTCP commands and error/response codes. This function returns the ID of +// the registered callback for later management. func (irc *Connection) AddCallback(eventcode string, callback func(*Event)) string { eventcode = strings.ToUpper(eventcode) From 499007f2d741912ceba70d5394df31d72d2da271 Mon Sep 17 00:00:00 2001 From: tpltnt Date: Fri, 14 Feb 2014 17:10:06 +0100 Subject: [PATCH 10/11] wording fix --- irc_struct.go | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/irc_struct.go b/irc_struct.go index de05e83..a0d468a 100644 --- a/irc_struct.go +++ b/irc_struct.go @@ -56,7 +56,9 @@ type Event struct { } -// Extract the last message from an Event. This function eventually returns an empty string. +// Retrieve the last message from Event arguments. +// This function leaves the arguments untouched and +// returns an empty string if there are none. func (e *Event) Message() string { if len(e.Arguments) == 0 { return "" From 124f756eb408e46a551c1b6a8e708314ed346e48 Mon Sep 17 00:00:00 2001 From: tpltnt Date: Fri, 14 Feb 2014 17:56:19 +0100 Subject: [PATCH 11/11] (ocd) markup fix --- README.markdown | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/README.markdown b/README.markdown index 2646543..607ecd7 100644 --- a/README.markdown +++ b/README.markdown @@ -1,11 +1,11 @@ Description ----------- +----------- Event based irc client library. Features ---------- +-------- * Event based. Register Callbacks for the events you need to handle. * Handles basic irc demands for you * Standard CTCP @@ -13,15 +13,15 @@ Features * Detect stoned servers Install ----------- +------- $ go get github.com/thoj/go-ircevent Example ----------- +------- See test/irc_test.go Events for callbacks ---------- +-------------------- * 001 Welcome * PING * CTCP Unknown CTCP @@ -39,7 +39,7 @@ Events for callbacks AddCallback Example ---------- +------------------- ircobj.AddCallback("PRIVMSG", func(event *irc.Event) { //e.Message() contains the message //e.Nick Contains the sender