Initial commit
This commit is contained in:
commit
6fb1ecc090
13
LICENSE
Normal file
13
LICENSE
Normal file
@ -0,0 +1,13 @@
|
||||
Copyright (c) 2016, Daniel Oaks
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
|
||||
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
|
||||
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
||||
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
||||
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
PERFORMANCE OF THIS SOFTWARE.
|
5
README.md
Normal file
5
README.md
Normal file
@ -0,0 +1,5 @@
|
||||
# gIRC-go
|
||||
|
||||
I write an IRC library in Python called [gIRC](https://github.com/DanielOaks/girc). This is something similar, but for Go!
|
||||
|
||||
I don't recommend using this in production in any way at all yet.
|
178
message.go
Normal file
178
message.go
Normal file
@ -0,0 +1,178 @@
|
||||
// written by Daniel Oaks <daniel@danieloaks.net>
|
||||
// released under the CC0 Public Domain license
|
||||
|
||||
package girc
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// TagValue represents the value of a tag. This is because tags may have
|
||||
// no value at all or just an empty value, and this can represent both
|
||||
// using the HasValue attribute.
|
||||
type TagValue struct {
|
||||
HasValue bool
|
||||
Value string
|
||||
}
|
||||
|
||||
// IrcMessage represents an IRC message, as defined by the RFCs and as
|
||||
// extended by the IRCv3 Message Tags specification with the introduction
|
||||
// of message tags.
|
||||
type IrcMessage struct {
|
||||
Tags map[string]TagValue
|
||||
Prefix string
|
||||
Command string
|
||||
Params []string
|
||||
}
|
||||
|
||||
// ParseLine creates and returns an IrcMessage from the given IRC line.
|
||||
func ParseLine(line string) (IrcMessage, error) {
|
||||
line = strings.Trim(line, "\r\n")
|
||||
var ircmsg IrcMessage
|
||||
|
||||
// tags
|
||||
ircmsg.Tags = make(map[string]TagValue)
|
||||
if line[0] == '@' {
|
||||
splitLine := strings.SplitN(line, " ", 2)
|
||||
tags := splitLine[0][1:]
|
||||
line = strings.TrimLeft(splitLine[1], " ")
|
||||
|
||||
for _, fulltag := range strings.Split(tags, ";") {
|
||||
var name string
|
||||
var val TagValue
|
||||
if strings.Contains(fulltag, "=") {
|
||||
val.HasValue = true
|
||||
splittag := strings.SplitN(fulltag, "=", 2)
|
||||
name = splittag[0]
|
||||
val.Value = splittag[1]
|
||||
// TODO: unescape values
|
||||
} else {
|
||||
name = fulltag
|
||||
val.HasValue = false
|
||||
}
|
||||
|
||||
ircmsg.Tags[name] = val
|
||||
}
|
||||
}
|
||||
|
||||
// prefix
|
||||
if line[0] == ':' {
|
||||
splitLine := strings.SplitN(line, " ", 2)
|
||||
ircmsg.Prefix = splitLine[0][1:]
|
||||
line = strings.TrimLeft(splitLine[1], " ")
|
||||
}
|
||||
|
||||
// command
|
||||
splitLine := strings.SplitN(line, " ", 2)
|
||||
ircmsg.Command = strings.ToUpper(splitLine[0])
|
||||
line = strings.TrimLeft(splitLine[1], " ")
|
||||
|
||||
// parameters
|
||||
for {
|
||||
// handle trailing
|
||||
if line[0] == ':' {
|
||||
ircmsg.Params = append(ircmsg.Params, line[1:])
|
||||
break
|
||||
}
|
||||
|
||||
// regular params
|
||||
splitLine := strings.SplitN(line, " ", 2)
|
||||
ircmsg.Params = append(ircmsg.Params, splitLine[0])
|
||||
|
||||
if len(splitLine) > 1 {
|
||||
line = strings.TrimLeft(splitLine[1], " ")
|
||||
} else {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
return ircmsg, nil
|
||||
}
|
||||
|
||||
// MakeMessage provides a simple way to create a new IrcMessage.
|
||||
func MakeMessage(tags *map[string]TagValue, prefix string, command string, params ...string) IrcMessage {
|
||||
var ircmsg IrcMessage
|
||||
|
||||
ircmsg.Tags = make(map[string]TagValue)
|
||||
if tags != nil {
|
||||
for tag, value := range *tags {
|
||||
ircmsg.Tags[tag] = value
|
||||
}
|
||||
}
|
||||
|
||||
ircmsg.Prefix = prefix
|
||||
ircmsg.Command = command
|
||||
ircmsg.Params = params
|
||||
|
||||
return ircmsg
|
||||
}
|
||||
|
||||
// NoTagValue returns an empty TagValue.
|
||||
func NoTagValue() TagValue {
|
||||
var tag TagValue
|
||||
tag.HasValue = false
|
||||
return tag
|
||||
}
|
||||
|
||||
// MakeTagValue returns a TagValue with a defined value.
|
||||
func MakeTagValue(value string) TagValue {
|
||||
var tag TagValue
|
||||
tag.HasValue = true
|
||||
tag.Value = value
|
||||
return tag
|
||||
}
|
||||
|
||||
// Line returns a sendable line created from an IrcMessage.
|
||||
func (ircmsg *IrcMessage) Line() (string, error) {
|
||||
var line string
|
||||
|
||||
if len(ircmsg.Command) < 1 {
|
||||
return "", errors.New("irc: IRC messages MUST have a command")
|
||||
}
|
||||
|
||||
if len(ircmsg.Tags) > 0 {
|
||||
line += "@"
|
||||
|
||||
for tag, val := range ircmsg.Tags {
|
||||
line += tag
|
||||
|
||||
if val.HasValue {
|
||||
line += "="
|
||||
line += val.Value
|
||||
// TODO: escape values
|
||||
}
|
||||
|
||||
line += ";"
|
||||
}
|
||||
// TODO: this is ugly, but it works for now
|
||||
line = strings.TrimSuffix(line, ";")
|
||||
|
||||
line += " "
|
||||
}
|
||||
|
||||
if len(ircmsg.Prefix) > 0 {
|
||||
line += ":"
|
||||
line += ircmsg.Prefix
|
||||
line += " "
|
||||
}
|
||||
|
||||
line += ircmsg.Command
|
||||
|
||||
if len(ircmsg.Params) > 0 {
|
||||
for i, param := range ircmsg.Params {
|
||||
line += " "
|
||||
if strings.Contains(param, " ") || len(param) < 1 {
|
||||
if i != len(ircmsg.Params)-1 {
|
||||
return "", errors.New("irc: Cannot have a param with spaces or an empty param before the last parameter")
|
||||
}
|
||||
line += ":"
|
||||
}
|
||||
line += param
|
||||
}
|
||||
}
|
||||
|
||||
line += "\r\n"
|
||||
|
||||
return line, nil
|
||||
}
|
Loading…
Reference in New Issue
Block a user