diff --git a/ansible/group_vars/all.yml b/ansible/group_vars/all.yml index 57db1f6..4b3946f 100755 --- a/ansible/group_vars/all.yml +++ b/ansible/group_vars/all.yml @@ -7,5 +7,11 @@ email: !vault | 35666538386231343533333231646131383734663834663039636235313237636366343535376366 3438353430666537630a323338663565366439353163646435633738653563393330613064363163 66356363623063373532626262343361663933623132653162633034396131623038 -admin: gempir -channels: "gempir,pajlada" \ No newline at end of file +username: gempbot +oauth: !vault | + $ANSIBLE_VAULT;1.1;AES256 + 34306435393365666330346435616335386537653565393433656436383131343063356666623930 + 6137316537306234353665333065636636663363383038640a653735356262613362666561383033 + 33343936646165393262353239633335653563373438353765636463373439653235643535333633 + 6163656464313337350a323039656238346538666132646530386261643336613238356264363132 + 36623964383333333965343132626662623832626663656631366563613139373832 \ No newline at end of file diff --git a/ansible/roles/bot/templates/config.j2 b/ansible/roles/bot/templates/config.j2 index 18f43f3..48b696d 100755 --- a/ansible/roles/bot/templates/config.j2 +++ b/ansible/roles/bot/templates/config.j2 @@ -1,5 +1,22 @@ { - "admin": "{{ admin }}", + "admin": "gempir", "logsDirectory": "/var/justlog", - "channels": ["gempir", "pajlada"] + "username": "{{ username }}", + "oauth": "{{ oauth }}", + "channels": [ + "gempir", + "pajlada", + "gempbot", + "forsen", + "jaxerie", + "nymn", + "nani", + "trizze", + "chancu", + "tearon", + "thiccanimegrili", + "razq", + "krakenbul", + "infinitegachi" + ] } \ No newline at end of file diff --git a/api/logs.go b/api/logs.go index a1aec10..4108075 100644 --- a/api/logs.go +++ b/api/logs.go @@ -8,24 +8,15 @@ import ( "math/rand" "net/http" "os" - "regexp" "strconv" "strings" "time" + "github.com/gempir/go-twitch-irc" "github.com/labstack/echo" + "github.com/labstack/gommon/log" ) -var ( - logReg = regexp.MustCompile(`\[(.*)\]\s(.*?):\s(.*)`) -) - -// ErrorJSON simple json for default error response -type ErrorJSON struct { - Error string `json:"Error"` -} - -// RandomQuoteJSON simple json to output rq type RandomQuoteJSON struct { Channel string `json:"channel"` Username string `json:"username"` @@ -33,27 +24,18 @@ type RandomQuoteJSON struct { Timestamp string `json:"timestamp"` } -// AllChannelsJSON api response type AllChannelsJSON struct { Channels []string `json:"channels"` } -// LogMessage for json -type LogMessage struct { - Username string `json:"username"` - Message string `json:"message"` - Timestamp string `json:"timestamp"` -} - func (s *Server) getCurrentUserLogs(c echo.Context) error { - channel := strings.ToLower(c.Param("channel")) - channel = strings.TrimSpace(channel) - year := time.Now().Year() - month := time.Now().Month().String() - username := c.Param("username") - username = strings.ToLower(strings.TrimSpace(username)) + channelID := c.Param("channelid") + userID := c.Param("userid") - redirectURL := fmt.Sprintf("/channel/%s/user/%s/%d/%s", channel, username, year, month) + year := time.Now().Year() + month := int(time.Now().Month()) + + redirectURL := fmt.Sprintf("/channelid/%s/userid/%s/%d/%d", channelID, userID, year, month) return c.Redirect(303, redirectURL) } @@ -65,145 +47,16 @@ func (s *Server) getAllChannels(c echo.Context) error { } func (s *Server) getCurrentChannelLogs(c echo.Context) error { - channel := strings.ToLower(c.Param("channel")) - channel = strings.TrimSpace(channel) + channelID := c.Param("channelid") year := time.Now().Year() - month := time.Now().Month().String() + month := int(time.Now().Month()) day := time.Now().Day() - redirectURL := fmt.Sprintf("/channel/%s/%d/%s/%d", channel, year, month, day) + redirectURL := fmt.Sprintf("/channelid/%s/%d/%d/%d", channelID, year, month, day) return c.Redirect(http.StatusSeeOther, redirectURL) } -func (s *Server) getDatedChannelLogs(c echo.Context) error { - channel := strings.ToLower(c.Param("channel")) - channel = strings.TrimSpace(channel) - year := c.Param("year") - month := strings.Title(c.Param("month")) - day := c.Param("day") - - if year == "" || month == "" { - year = strconv.Itoa(time.Now().Year()) - month = time.Now().Month().String() - } - - content := "" - - file := fmt.Sprintf(s.logPath+"/%s/%s/%s/%s/channel.txt", channel, year, month, day) - if _, err := os.Stat(file + ".gz"); err == nil { - file = file + ".gz" - f, err := os.Open(file) - if err != nil { - errJSON := new(ErrorJSON) - errJSON.Error = "error finding logs" - return c.JSON(http.StatusNotFound, errJSON) - } - gz, err := gzip.NewReader(f) - scanner := bufio.NewScanner(gz) - if err != nil { - errJSON := new(ErrorJSON) - errJSON.Error = "error finding logs" - return c.JSON(http.StatusNotFound, errJSON) - } - - for scanner.Scan() { - line := scanner.Text() - content += line + "\r\n" - } - return c.String(http.StatusOK, content) - } - - return c.File(file) -} - -func (s *Server) getDatedUserLogs(c echo.Context) error { - channel := strings.ToLower(c.Param("channel")) - channel = strings.TrimSpace(channel) - year := c.Param("year") - month := strings.Title(c.Param("month")) - username := c.Param("username") - username = strings.ToLower(strings.TrimSpace(username)) - - if year == "" || month == "" { - year = strconv.Itoa(time.Now().Year()) - month = time.Now().Month().String() - } - - content := "" - - file := fmt.Sprintf(s.logPath+"/%s/%s/%s/%s.txt", channel, year, month, username) - if _, err := os.Stat(file + ".gz"); err == nil { - file = file + ".gz" - f, err := os.Open(file) - if err != nil { - errJSON := new(ErrorJSON) - errJSON.Error = "error finding logs" - return c.JSON(http.StatusNotFound, errJSON) - } - gz, err := gzip.NewReader(f) - scanner := bufio.NewScanner(gz) - if err != nil { - errJSON := new(ErrorJSON) - errJSON.Error = "error finding logs" - return c.JSON(http.StatusNotFound, errJSON) - } - - if c.Request().Header.Get("Content-Type") == "application/json" { - - messages := []LogMessage{} - - for scanner.Scan() { - line := scanner.Text() - result := logReg.FindStringSubmatch(line) - - message := LogMessage{Username: result[2], Message: result[3], Timestamp: result[1]} - - messages = append(messages, message) - } - - return c.JSON(http.StatusOK, messages) - } - - for scanner.Scan() { - line := scanner.Text() - content += line + "\r\n" - } - return c.String(http.StatusOK, content) - } - - if c.Request().Header.Get("Content-Type") == "application/json" { - - openFile, err := os.Open(file) - if err != nil { - errJSON := new(ErrorJSON) - errJSON.Error = "error finding logs" - return c.JSON(http.StatusNotFound, errJSON) - } - defer openFile.Close() - - scanner := bufio.NewScanner(openFile) - - messages := []LogMessage{} - - for scanner.Scan() { - line := scanner.Text() - result := logReg.FindStringSubmatch(line) - - message := LogMessage{Username: result[2], Message: result[3], Timestamp: result[1]} - - messages = append(messages, message) - } - - return c.JSON(http.StatusOK, messages) - } - - return c.File(file) -} - func (s *Server) getRandomQuote(c echo.Context) error { - errJSON := new(ErrorJSON) - errJSON.Error = "error finding logs" - username := c.Param("username") username = strings.ToLower(strings.TrimSpace(username)) channel := strings.ToLower(c.Param("channel")) @@ -227,9 +80,7 @@ func (s *Server) getRandomQuote(c echo.Context) error { } } if len(userLogs) < 1 { - errJSON := new(ErrorJSON) - errJSON.Error = "error finding logs" - return c.JSON(http.StatusNotFound, errJSON) + return c.JSON(http.StatusNotFound, "error finding logs") } for _, logFile := range userLogs { @@ -267,3 +118,102 @@ func (s *Server) getRandomQuote(c echo.Context) error { return c.String(http.StatusOK, lineSplit[1]) } + +func (s *Server) getUserLogs(c echo.Context) error { + channelID := c.Param("channelid") + userID := c.Param("userid") + + yearStr := c.Param("year") + monthStr := c.Param("month") + + year, err := strconv.Atoi(yearStr) + if err != nil { + log.Error(err) + return c.JSON(http.StatusInternalServerError, "Invalid year") + } + month, err := strconv.Atoi(monthStr) + if err != nil { + log.Error(err) + return c.JSON(http.StatusInternalServerError, "Invalid month") + } + + logMessages, err := s.fileLogger.ReadLogForUser(channelID, userID, year, month) + if err != nil { + log.Error(err) + return c.JSON(http.StatusInternalServerError, "Failure reading log") + } + + var logResult chatLog + + for _, rawMessage := range logMessages { + channel, user, parsedMessage := twitch.ParseMessage(rawMessage) + + message := chatMessage{ + Timestamp: timestamp{parsedMessage.Time}, + Username: user.Username, + Text: parsedMessage.Text, + Type: parsedMessage.Type, + Channel: channel, + } + + logResult.Messages = append(logResult.Messages, message) + } + + if c.Request().Header.Get("Content-Type") == "application/json" || c.QueryParam("type") == "json" { + return writeJSONResponse(c, &logResult) + } + + return writeTextResponse(c, &logResult) +} + +func (s *Server) getChannelLogs(c echo.Context) error { + channelID := c.Param("channelid") + + yearStr := c.Param("year") + monthStr := c.Param("month") + dayStr := c.Param("day") + + year, err := strconv.Atoi(yearStr) + if err != nil { + log.Error(err) + return c.JSON(http.StatusInternalServerError, "Invalid year") + } + month, err := strconv.Atoi(monthStr) + if err != nil { + log.Error(err) + return c.JSON(http.StatusInternalServerError, "Invalid month") + } + day, err := strconv.Atoi(dayStr) + if err != nil { + log.Error(err) + return c.JSON(http.StatusInternalServerError, "Invalid day") + } + + logMessages, err := s.fileLogger.ReadLogForChannel(channelID, year, month, day) + if err != nil { + log.Error(err) + return c.JSON(http.StatusInternalServerError, "Failure reading log") + } + + var logResult chatLog + + for _, rawMessage := range logMessages { + channel, user, parsedMessage := twitch.ParseMessage(rawMessage) + + message := chatMessage{ + Timestamp: timestamp{parsedMessage.Time}, + Username: user.Username, + Text: parsedMessage.Text, + Type: parsedMessage.Type, + Channel: channel, + } + + logResult.Messages = append(logResult.Messages, message) + } + + if c.Request().Header.Get("Content-Type") == "application/json" || c.QueryParam("type") == "json" { + return writeJSONResponse(c, &logResult) + } + + return writeTextResponse(c, &logResult) +} diff --git a/api/main.go b/api/main.go new file mode 100644 index 0000000..c34c1a8 --- /dev/null +++ b/api/main.go @@ -0,0 +1,146 @@ +package api + +import ( + "encoding/json" + "errors" + "fmt" + "net/http" + "strconv" + "strings" + "time" + + twitch "github.com/gempir/go-twitch-irc" + jsoniter "github.com/json-iterator/go" + "github.com/labstack/echo" +) + +type order string + +var ( + orderDesc order = "DESC" + orderAsc order = "ASC" +) + +type chatLog struct { + Messages []chatMessage `json:"messages"` +} + +type chatMessage struct { + Text string `json:"text"` + Username string `json:"username"` + Channel string `json:"channel"` + Timestamp timestamp `json:"timestamp"` + Type twitch.MessageType `json:"type"` +} + +type timestamp struct { + time.Time +} + +func (t timestamp) MarshalJSON() ([]byte, error) { + return []byte("\"" + t.UTC().Format(time.RFC3339) + "\""), nil +} + +func (t *timestamp) UnmarshalJSON(data []byte) error { + goTime, err := time.Parse(time.RFC3339, strings.TrimSuffix(strings.TrimPrefix(string(data[:]), "\""), "\"")) + if err != nil { + return err + } + *t = timestamp{ + goTime, + } + return nil +} + +func parseFromTo(from, to string, limit float64) (time.Time, time.Time, error) { + var fromTime time.Time + var toTime time.Time + + if from == "" && to == "" { + fromTime = time.Now().AddDate(0, -1, 0) + toTime = time.Now() + } else if from == "" && to != "" { + var err error + toTime, err = parseTimestamp(to) + if err != nil { + return fromTime, toTime, fmt.Errorf("Can't parse to timestamp: %s", err) + } + fromTime = toTime.AddDate(0, -1, 0) + } else if from != "" && to == "" { + var err error + fromTime, err = parseTimestamp(from) + if err != nil { + return fromTime, toTime, fmt.Errorf("Can't parse from timestamp: %s", err) + } + toTime = fromTime.AddDate(0, 1, 0) + } else { + var err error + + fromTime, err = parseTimestamp(from) + if err != nil { + return fromTime, toTime, fmt.Errorf("Can't parse from timestamp: %s", err) + } + toTime, err = parseTimestamp(to) + if err != nil { + return fromTime, toTime, fmt.Errorf("Can't parse to timestamp: %s", err) + } + + if toTime.Sub(fromTime).Hours() > limit { + return fromTime, toTime, errors.New("Timespan too big") + } + } + + return fromTime, toTime, nil +} + +func writeTextResponse(c echo.Context, cLog *chatLog) error { + c.Response().WriteHeader(http.StatusOK) + + for _, cMessage := range cLog.Messages { + switch cMessage.Type { + case twitch.PRIVMSG: + c.Response().Write([]byte(fmt.Sprintf("[%s] #%s %s: %s\r\n", cMessage.Timestamp.Format("2006-01-2 15:04:05"), cMessage.Channel, cMessage.Username, cMessage.Text))) + case twitch.CLEARCHAT: + c.Response().Write([]byte(fmt.Sprintf("[%s] #%s %s\r\n", cMessage.Timestamp.Format("2006-01-2 15:04:05"), cMessage.Channel, cMessage.Text))) + } + } + + return nil +} + +func writeJSONResponse(c echo.Context, logResult *chatLog) error { + _, stream := c.QueryParams()["stream"] + if stream { + c.Response().Header().Set(echo.HeaderContentType, echo.MIMEApplicationJSONCharsetUTF8) + c.Response().WriteHeader(http.StatusOK) + + return json.NewEncoder(c.Response()).Encode(logResult) + } + + json := jsoniter.ConfigCompatibleWithStandardLibrary + data, err := json.Marshal(logResult) + if err != nil { + return c.JSON(http.StatusInternalServerError, err.Error()) + } + + return c.Blob(http.StatusOK, echo.MIMEApplicationJSONCharsetUTF8, data) +} + +func parseTimestamp(timestamp string) (time.Time, error) { + + i, err := strconv.ParseInt(timestamp, 10, 64) + if err != nil { + return time.Now(), err + } + return time.Unix(i, 0), nil +} + +func buildOrder(c echo.Context) order { + dataOrder := orderAsc + _, reverse := c.QueryParams()["reverse"] + if reverse { + dataOrder = orderDesc + } + + return dataOrder +} diff --git a/api/server.go b/api/server.go index 9d36e85..fc12a4d 100644 --- a/api/server.go +++ b/api/server.go @@ -1,34 +1,33 @@ package api import ( - "fmt" "net/http" + "github.com/gempir/justlog/filelog" "github.com/labstack/echo" "github.com/labstack/echo/middleware" ) -// Server api server type Server struct { - port string - logPath string - channels []string + listenAddress string + logPath string + fileLogger *filelog.Logger + channels []string } -// NewServer create Server -func NewServer(logPath string) Server { +func NewServer(logPath string, listenAddress string, fileLogger *filelog.Logger) Server { return Server{ - logPath: logPath, - channels: []string{}, + listenAddress: listenAddress, + logPath: logPath, + fileLogger: fileLogger, + channels: []string{}, } } -// AddChannel to in-memory store to serve joined channels func (s *Server) AddChannel(channel string) { s.channels = append(s.channels, channel) } -// Init api server func (s *Server) Init() { e := echo.New() @@ -44,13 +43,12 @@ func (s *Server) Init() { e.GET("/", func(c echo.Context) error { return c.String(http.StatusOK, "Hello, World!") }) - e.GET("/channel/:channel/user/:username", s.getCurrentUserLogs) - e.GET("/channel", s.getAllChannels) - e.GET("/channel/:channel", s.getCurrentChannelLogs) - e.GET("/channel/:channel/:year/:month/:day", s.getDatedChannelLogs) - e.GET("/channel/:channel/user/:username/:year/:month", s.getDatedUserLogs) - e.GET("/channel/:channel/user/:username/random", s.getRandomQuote) + e.GET("/channelid/:channelid/user/:userid", s.getCurrentUserLogs) + e.GET("/channelid", s.getAllChannels) + e.GET("/channelid/:channelid", s.getCurrentChannelLogs) + e.GET("/channelid/:channelid/:year/:month/:day", s.getChannelLogs) + e.GET("/channelid/:channelid/userid/:userid/:year/:month", s.getUserLogs) + e.GET("/channelid/:channelid/userid/:userid/random", s.getRandomQuote) - fmt.Println("starting API on port :8025") - e.Logger.Fatal(e.Start(":8025")) + e.Logger.Fatal(e.Start(s.listenAddress)) } diff --git a/config.json b/config.json index 3eec956..bb72553 100644 --- a/config.json +++ b/config.json @@ -1,5 +1,7 @@ { "admin": "gempir", "logsDirectory": "./logs", + "username": "gempbot", + "oauth": "cg74a9xb4le868tctmelk7eidqtrra", "channels": ["gempir", "pajlada"] } \ No newline at end of file diff --git a/filelog/channellog.go b/filelog/channellog.go index 7e86316..8394047 100644 --- a/filelog/channellog.go +++ b/filelog/channellog.go @@ -1,33 +1,76 @@ package filelog import ( + "bufio" + "compress/gzip" + "errors" "fmt" + "io" "os" + "strings" "github.com/gempir/go-twitch-irc" ) -// LogMessageForChannel file log func (l *Logger) LogMessageForChannel(channel string, user twitch.User, message twitch.Message) error { year := message.Time.Year() - month := message.Time.Month() + month := int(message.Time.Month()) day := message.Time.Day() - err := os.MkdirAll(fmt.Sprintf(l.logPath+"/%s/%d/%s/%d", channel, year, month, day), 0755) + err := os.MkdirAll(fmt.Sprintf(l.logPath+"/%s/%d/%d/%d", message.Tags["room-id"], year, month, day), 0740) if err != nil { return err } - filename := fmt.Sprintf(l.logPath+"/%s/%d/%s/%d/channel.txt", channel, year, month, day) + filename := fmt.Sprintf(l.logPath+"/%s/%d/%d/%d/channel.txt", message.Tags["room-id"], year, month, day) - file, err := os.OpenFile(filename, os.O_APPEND|os.O_WRONLY|os.O_CREATE, 0755) + file, err := os.OpenFile(filename, os.O_APPEND|os.O_WRONLY|os.O_CREATE, 0640) if err != nil { return err } defer file.Close() - contents := fmt.Sprintf("[%s] %s: %s\r\n", message.Time.Format("2006-01-2 15:04:05"), user.Username, message.Text) - if _, err = file.WriteString(contents); err != nil { + if _, err = file.WriteString(message.Raw + "\r\n"); err != nil { return err } return nil } + +func (l *Logger) ReadLogForChannel(channelID string, year int, month int, day int) ([]string, error) { + filename := fmt.Sprintf(l.logPath+"/%s/%d/%d/%d/channel.txt", channelID, year, month, day) + + if _, err := os.Stat(filename); err != nil { + filename = filename + ".gz" + } + + f, err := os.Open(filename) + if err != nil { + return []string{}, errors.New("file not found") + } + defer f.Close() + + var reader io.Reader + + if strings.HasSuffix(filename, ".gz") { + gz, err := gzip.NewReader(f) + if err != nil { + return []string{}, errors.New("file gzip not readable") + } + reader = gz + } else { + reader = f + } + + scanner := bufio.NewScanner(reader) + if err != nil { + return []string{}, errors.New("file not readable") + } + + content := []string{} + + for scanner.Scan() { + line := scanner.Text() + content = append(content, line) + } + + return content, nil +} diff --git a/filelog/userlog.go b/filelog/userlog.go index 2d2b4f9..7e3d062 100644 --- a/filelog/userlog.go +++ b/filelog/userlog.go @@ -1,43 +1,84 @@ package filelog import ( + "bufio" + "compress/gzip" + "errors" "fmt" + "io" "os" + "strings" "github.com/gempir/go-twitch-irc" ) -// Logger logger struct type Logger struct { logPath string } -// NewFileLogger create file logger func NewFileLogger(logPath string) Logger { return Logger{ logPath: logPath, } } -// LogMessageForUser log in file func (l *Logger) LogMessageForUser(channel string, user twitch.User, message twitch.Message) error { year := message.Time.Year() - month := message.Time.Month() - err := os.MkdirAll(fmt.Sprintf(l.logPath+"/%s/%d/%s/", channel, year, month), 0755) + month := int(message.Time.Month()) + err := os.MkdirAll(fmt.Sprintf(l.logPath+"/%s/%d/%d/", message.Tags["room-id"], year, month), 0740) if err != nil { return err } - filename := fmt.Sprintf(l.logPath+"/%s/%d/%s/%s.txt", channel, year, month, user.Username) + filename := fmt.Sprintf(l.logPath+"/%s/%d/%d/%s.txt", message.Tags["room-id"], year, month, user.UserID) - file, err := os.OpenFile(filename, os.O_APPEND|os.O_WRONLY|os.O_CREATE, 0755) + file, err := os.OpenFile(filename, os.O_APPEND|os.O_WRONLY|os.O_CREATE, 0640) if err != nil { return err } defer file.Close() - contents := fmt.Sprintf("[%s] %s: %s\r\n", message.Time.Format("2006-01-2 15:04:05"), user.Username, message.Text) - if _, err = file.WriteString(contents); err != nil { + if _, err = file.WriteString(message.Raw + "\r\n"); err != nil { return err } return nil } + +func (l *Logger) ReadLogForUser(channelID string, userID string, year int, month int) ([]string, error) { + filename := fmt.Sprintf(l.logPath+"/%s/%d/%d/%s.txt", channelID, year, month, userID) + + if _, err := os.Stat(filename); err != nil { + filename = filename + ".gz" + } + + f, err := os.Open(filename) + if err != nil { + return []string{}, errors.New("file not found") + } + defer f.Close() + + var reader io.Reader + + if strings.HasSuffix(filename, ".gz") { + gz, err := gzip.NewReader(f) + if err != nil { + return []string{}, errors.New("file gzip not readable") + } + reader = gz + } else { + reader = f + } + + scanner := bufio.NewScanner(reader) + if err != nil { + return []string{}, errors.New("file not readable") + } + + content := []string{} + + for scanner.Scan() { + line := scanner.Text() + content = append(content, line) + } + + return content, nil +} diff --git a/helix/user.go b/helix/user.go new file mode 100644 index 0000000..afb1b43 --- /dev/null +++ b/helix/user.go @@ -0,0 +1 @@ +package helix diff --git a/humanize/time.go b/humanize/time.go index 34c3b62..fcfebc9 100644 --- a/humanize/time.go +++ b/humanize/time.go @@ -16,60 +16,48 @@ func formatDiff(years, months, days, hours, mins, secs int) string { switch years { case 1: since += fmt.Sprintf("%d year ", years) - break default: since += fmt.Sprintf("%d years ", years) - break } } if months > 0 { switch months { case 1: since += fmt.Sprintf("%d month ", months) - break default: since += fmt.Sprintf("%d months ", months) - break } } if days > 0 { switch days { case 1: since += fmt.Sprintf("%d day ", days) - break default: since += fmt.Sprintf("%d days ", days) - break } } if hours > 0 { switch hours { case 1: since += fmt.Sprintf("%d hour ", hours) - break default: since += fmt.Sprintf("%d hours ", hours) - break } } if mins > 0 && days == 0 && months == 0 && years == 0 { switch mins { case 1: since += fmt.Sprintf("%d min ", mins) - break default: since += fmt.Sprintf("%d mins ", mins) - break } } if secs > 0 && days == 0 && months == 0 && years == 0 && hours == 0 { switch secs { case 1: since += fmt.Sprintf("%d sec ", secs) - break default: since += fmt.Sprintf("%d secs ", secs) - break } } return strings.TrimSpace(since) diff --git a/main.go b/main.go index a0a714a..8df1dda 100644 --- a/main.go +++ b/main.go @@ -3,7 +3,6 @@ package main import ( "encoding/json" "flag" - "fmt" "os" "time" @@ -19,6 +18,9 @@ import ( type config struct { LogsDirectory string `json:"logsDirectory"` + Username string `json:"username"` + OAuth string `json:"oauth"` + ListenAddress string `json:"listenAddress"` Admin string `json:"admin"` Channels []string `json:"channels"` } @@ -34,14 +36,20 @@ func main() { flag.Parse() cfg = loadConfiguration(*configFile) - apiServer := api.NewServer(cfg.LogsDirectory) - go apiServer.Init() - - twitchClient := twitch.NewClient("justinfan123123", "oauth:123123123") + twitchClient := twitch.NewClient(cfg.Username, "oauth:"+cfg.OAuth) fileLogger := filelog.NewFileLogger(cfg.LogsDirectory) + if strings.HasPrefix(cfg.Username, "justinfan") { + log.Info("Bot joining anonymous") + } else { + log.Info("Bot joining as user " + cfg.Username) + } + + apiServer := api.NewServer(cfg.LogsDirectory, cfg.ListenAddress, &fileLogger) + go apiServer.Init() + for _, channel := range cfg.Channels { - fmt.Println("Joining " + channel) + log.Info("Joining " + channel) twitchClient.Join(channel) apiServer.AddChannel(channel) } @@ -85,22 +93,36 @@ func main() { }() }) - twitchClient.Connect() + log.Fatal(twitchClient.Connect()) } func loadConfiguration(file string) config { log.Info("Loading config from " + file) - var cfg config + + // setup defaults + cfg := config{ + LogsDirectory: "./logs", + ListenAddress: "127.0.0.1:8025", + Username: "justinfan777777", + OAuth: "oauth:777777777", + Channels: []string{}, + Admin: "gempir", + } + configFile, err := os.Open(file) + if err != nil { + log.Fatal(err) + } defer configFile.Close() + + jsonParser := json.NewDecoder(configFile) + err = jsonParser.Decode(&cfg) if err != nil { log.Fatal(err) } - jsonParser := json.NewDecoder(configFile) - jsonParser.Decode(&cfg) - cfg.LogsDirectory = strings.TrimSuffix(cfg.LogsDirectory, "/") + cfg.OAuth = strings.TrimPrefix(cfg.OAuth, "oauth:") return cfg }