summaryrefslogtreecommitdiff
path: root/events.go
blob: 10bb31ca7c48e628f7dc296c84679032f26697ce (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
/*
goircd -- minimalistic simple Internet Relay Chat (IRC) server
Copyright (C) 2014-2016 Sergey Matveev <stargrave@stargrave.org>

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

package main

import (
	"fmt"
	"io/ioutil"
	"log"
	"os"
	"path"
	"time"
)

const (
	EventNew   = iota
	EventDel   = iota
	EventMsg   = iota
	EventTopic = iota
	EventWho   = iota
	EventMode  = iota
	EventTerm  = iota
	EventTick  = iota
	FormatMsg  = "[%s] <%s> %s\n"
	FormatMeta = "[%s] * %s %s\n"
)

var (
	logSink   chan LogEvent   = make(chan LogEvent)
	stateSink chan StateEvent = make(chan StateEvent)
)

// Client events going from each of client
// They can be either NEW, DEL or unparsed MSG
type ClientEvent struct {
	client    *Client
	eventType int
	text      string
}

func (m ClientEvent) String() string {
	return string(m.eventType) + ": " + m.client.String() + ": " + m.text
}

// Logging in-room events
// Intended to tell when, where and who send a message or meta command
type LogEvent struct {
	where string
	who   string
	what  string
	meta  bool
}

// Logging events logger itself
// Each room's events are written to separate file in logdir
// Events include messages, topic and keys changes, joining and leaving
func Logger(logdir string, events <-chan LogEvent) {
	mode := os.O_CREATE | os.O_WRONLY | os.O_APPEND
	perm := os.FileMode(0660)
	var format string
	var logfile string
	var fd *os.File
	var err error
	for event := range events {
		logfile = path.Join(logdir, event.where+".log")
		fd, err = os.OpenFile(logfile, mode, perm)
		if err != nil {
			log.Println("Can not open logfile", logfile, err)
			continue
		}
		if event.meta {
			format = FormatMeta
		} else {
			format = FormatMsg
		}
		_, err = fd.WriteString(fmt.Sprintf(format, time.Now(), event.who, event.what))
		fd.Close()
		if err != nil {
			log.Println("Error writing to logfile", logfile, err)
		}
	}
}

type StateEvent struct {
	where string
	topic string
	key   string
}

// Room state events saver
// Room states shows that either topic or key has been changed
// Each room's state is written to separate file in statedir
func StateKeeper(statedir string, events <-chan StateEvent) {
	var fn string
	var data string
	var err error
	for event := range events {
		fn = path.Join(statedir, event.where)
		data = event.topic + "\n" + event.key + "\n"
		err = ioutil.WriteFile(fn, []byte(data), os.FileMode(0660))
		if err != nil {
			log.Printf("Can not write statefile %s: %v", fn, err)
		}
	}
}