spongy

A Unixy IRC client
git clone https://git.woozle.org/neale/spongy.git

spongy / spongyd
Neale Pickett  ·  2016-01-18

irc.go

  1package main
  2
  3import (
  4	"strconv"
  5	"strings"
  6)
  7
  8type Message struct {
  9	Unparsed   string
 10	Command    string
 11	FullSender string
 12	Sender     string
 13	Forum      string
 14	Args       []string
 15	Text       string
 16}
 17
 18func NewMessage(v string) (Message, error) {
 19	var m Message
 20	var parts []string
 21	var lhs string
 22
 23	m.Unparsed = v
 24	parts = strings.SplitN(v, " :", 2)
 25	if len(parts) == 2 {
 26		lhs = parts[0]
 27		m.Text = parts[1]
 28	} else {
 29		lhs = v
 30		m.Text = ""
 31	}
 32
 33	m.FullSender = "."
 34	m.Forum = "."
 35	m.Sender = "."
 36
 37	parts = strings.Split(lhs, " ")
 38	if parts[0][0] == ':' {
 39		m.FullSender = parts[0][1:]
 40		parts = parts[1:]
 41
 42		n, u, _ := SplitTarget(m.FullSender)
 43		if u != "" {
 44			m.Sender = n
 45		}
 46	}
 47
 48	m.Command = strings.ToUpper(parts[0])
 49	switch m.Command {
 50	case "PRIVMSG", "NOTICE":
 51		switch {
 52		case IsChannel(parts[1]):
 53			m.Forum = parts[1]
 54		case m.FullSender == ".":
 55			m.Forum = parts[1]
 56		default:
 57			m.Forum = m.Sender
 58		}
 59	case "PART", "MODE", "TOPIC", "KICK":
 60		m.Forum = parts[1]
 61		m.Args = parts[2:]
 62	case "JOIN":
 63		if len(parts) == 1 {
 64			m.Forum = m.Text
 65			m.Text = ""
 66		} else {
 67			m.Forum = parts[1]
 68		}
 69	case "INVITE":
 70		if m.Text != "" {
 71			m.Forum = m.Text
 72			m.Text = ""
 73		} else {
 74			m.Forum = parts[2]
 75		}
 76	case "NICK":
 77		if len(parts) > 1 {
 78			m.Sender = parts[1]
 79			m.Args = parts[2:]
 80		} else {
 81			m.Sender = m.Text
 82			m.Text = ""
 83			m.Args = parts[1:]
 84		}
 85		m.Forum = m.Sender
 86	case "353":
 87		m.Forum = parts[3]
 88	default:
 89		numeric, _ := strconv.Atoi(m.Command)
 90		if numeric >= 300 {
 91			if len(parts) > 2 {
 92				m.Forum = parts[2]
 93			}
 94		}
 95		m.Args = parts[1:]
 96	}
 97
 98	return m, nil
 99}
100
101func (m Message) String() string {
102	return m.Unparsed
103}
104
105func SplitTarget(s string) (string, string, string) {
106	var parts []string
107
108	parts = strings.SplitN(s, "!", 2)
109	if len(parts) == 1 {
110		return s, "", ""
111	}
112	nick := parts[0]
113	parts = strings.SplitN(parts[1], "@", 2)
114	if len(parts) == 1 {
115		return s, "", ""
116	}
117	return nick, parts[0], parts[1]
118}
119
120func IsChannel(s string) bool {
121	if s == "" {
122		return false
123	}
124
125	switch s[0] {
126	case '#', '+', '!', '&':
127		return true
128	default:
129		return false
130	}
131}