2017-03-08 21:38:01 +01:00
|
|
|
package api
|
|
|
|
|
|
|
|
import (
|
|
|
|
"bufio"
|
|
|
|
"compress/gzip"
|
|
|
|
"fmt"
|
|
|
|
"io/ioutil"
|
|
|
|
"math/rand"
|
|
|
|
"net/http"
|
|
|
|
"os"
|
|
|
|
"strconv"
|
|
|
|
"strings"
|
|
|
|
"time"
|
2017-09-13 21:12:11 +02:00
|
|
|
|
2018-12-02 14:53:01 +01:00
|
|
|
"github.com/gempir/go-twitch-irc"
|
2017-09-13 21:12:11 +02:00
|
|
|
"github.com/labstack/echo"
|
2018-12-02 19:23:54 +01:00
|
|
|
log "github.com/sirupsen/logrus"
|
2017-03-08 21:38:01 +01:00
|
|
|
)
|
|
|
|
|
2017-04-26 19:08:01 +02:00
|
|
|
type RandomQuoteJSON struct {
|
2017-09-13 21:12:11 +02:00
|
|
|
Channel string `json:"channel"`
|
|
|
|
Username string `json:"username"`
|
|
|
|
Message string `json:"message"`
|
|
|
|
Timestamp string `json:"timestamp"`
|
2017-03-08 21:38:01 +01:00
|
|
|
}
|
|
|
|
|
2018-03-02 20:18:12 +01:00
|
|
|
type AllChannelsJSON struct {
|
|
|
|
Channels []string `json:"channels"`
|
|
|
|
}
|
|
|
|
|
2017-03-11 11:33:50 +01:00
|
|
|
func (s *Server) getCurrentUserLogs(c echo.Context) error {
|
2018-12-02 14:53:01 +01:00
|
|
|
channelID := c.Param("channelid")
|
|
|
|
userID := c.Param("userid")
|
|
|
|
|
2017-03-11 21:51:08 +01:00
|
|
|
year := time.Now().Year()
|
2018-12-02 14:53:01 +01:00
|
|
|
month := int(time.Now().Month())
|
2017-03-08 21:38:01 +01:00
|
|
|
|
2018-12-02 14:53:01 +01:00
|
|
|
redirectURL := fmt.Sprintf("/channelid/%s/userid/%s/%d/%d", channelID, userID, year, month)
|
2017-03-08 21:38:01 +01:00
|
|
|
return c.Redirect(303, redirectURL)
|
|
|
|
}
|
|
|
|
|
2018-03-02 20:18:12 +01:00
|
|
|
func (s *Server) getAllChannels(c echo.Context) error {
|
2018-03-05 21:25:55 +01:00
|
|
|
response := new(AllChannelsJSON)
|
|
|
|
response.Channels = s.channels
|
2018-03-02 20:18:12 +01:00
|
|
|
|
2018-03-05 21:25:55 +01:00
|
|
|
return c.JSON(http.StatusOK, response)
|
|
|
|
}
|
2018-03-02 20:18:12 +01:00
|
|
|
|
2017-03-11 11:33:50 +01:00
|
|
|
func (s *Server) getCurrentChannelLogs(c echo.Context) error {
|
2018-12-02 14:53:01 +01:00
|
|
|
channelID := c.Param("channelid")
|
2017-03-11 21:51:08 +01:00
|
|
|
year := time.Now().Year()
|
2018-12-02 14:53:01 +01:00
|
|
|
month := int(time.Now().Month())
|
2017-03-11 21:51:08 +01:00
|
|
|
day := time.Now().Day()
|
2017-03-11 11:33:50 +01:00
|
|
|
|
2018-12-02 14:53:01 +01:00
|
|
|
redirectURL := fmt.Sprintf("/channelid/%s/%d/%d/%d", channelID, year, month, day)
|
2018-03-02 20:18:12 +01:00
|
|
|
return c.Redirect(http.StatusSeeOther, redirectURL)
|
2017-03-11 11:33:50 +01:00
|
|
|
}
|
|
|
|
|
2017-03-08 21:38:01 +01:00
|
|
|
func (s *Server) getRandomQuote(c echo.Context) error {
|
|
|
|
username := c.Param("username")
|
|
|
|
username = strings.ToLower(strings.TrimSpace(username))
|
|
|
|
channel := strings.ToLower(c.Param("channel"))
|
|
|
|
channel = strings.TrimSpace(channel)
|
|
|
|
|
|
|
|
var userLogs []string
|
|
|
|
var lines []string
|
|
|
|
|
2017-09-13 21:25:04 +02:00
|
|
|
years, _ := ioutil.ReadDir(s.logPath + "/" + channel)
|
2017-03-08 21:38:01 +01:00
|
|
|
for _, yearDir := range years {
|
|
|
|
year := yearDir.Name()
|
2017-09-13 21:25:04 +02:00
|
|
|
months, _ := ioutil.ReadDir(s.logPath + "/" + channel + "/" + year + "/")
|
2017-03-08 21:38:01 +01:00
|
|
|
for _, monthDir := range months {
|
|
|
|
month := monthDir.Name()
|
2017-09-13 21:12:11 +02:00
|
|
|
path := fmt.Sprintf("%s/%s/%s/%s/%s.txt", s.logPath, channel, year, month, username)
|
2017-03-08 21:38:01 +01:00
|
|
|
if _, err := os.Stat(path); err == nil {
|
|
|
|
userLogs = append(userLogs, path)
|
|
|
|
} else if _, err := os.Stat(path + ".gz"); err == nil {
|
2017-03-11 21:51:08 +01:00
|
|
|
userLogs = append(userLogs, path+".gz")
|
2017-03-08 21:38:01 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if len(userLogs) < 1 {
|
2018-12-02 14:53:01 +01:00
|
|
|
return c.JSON(http.StatusNotFound, "error finding logs")
|
2017-03-08 21:38:01 +01:00
|
|
|
}
|
|
|
|
|
2017-03-30 21:53:24 +02:00
|
|
|
for _, logFile := range userLogs {
|
2017-04-03 22:17:41 +02:00
|
|
|
f, _ := os.Open(logFile)
|
2017-03-08 21:38:01 +01:00
|
|
|
|
2017-03-30 21:53:24 +02:00
|
|
|
scanner := bufio.NewScanner(f)
|
2017-03-08 21:38:01 +01:00
|
|
|
|
2017-03-30 21:53:24 +02:00
|
|
|
if strings.HasSuffix(logFile, ".gz") {
|
|
|
|
gz, _ := gzip.NewReader(f)
|
|
|
|
scanner = bufio.NewScanner(gz)
|
|
|
|
}
|
2017-03-08 21:38:01 +01:00
|
|
|
|
2017-03-30 21:53:24 +02:00
|
|
|
for scanner.Scan() {
|
|
|
|
line := scanner.Text()
|
|
|
|
lines = append(lines, line)
|
|
|
|
}
|
|
|
|
f.Close()
|
2017-03-08 21:38:01 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
ranNum := rand.Intn(len(lines))
|
|
|
|
line := lines[ranNum]
|
|
|
|
lineSplit := strings.SplitN(line, "]", 2)
|
2017-04-26 19:08:01 +02:00
|
|
|
|
2017-09-13 21:12:11 +02:00
|
|
|
if c.Request().Header.Get("Content-Type") == "application/json" {
|
2017-04-26 19:08:01 +02:00
|
|
|
|
|
|
|
randomQ := RandomQuoteJSON{
|
2017-09-13 21:12:11 +02:00
|
|
|
Channel: channel,
|
|
|
|
Username: username,
|
|
|
|
Message: strings.TrimPrefix(lineSplit[1], " "+username+": "),
|
2017-04-26 19:08:01 +02:00
|
|
|
Timestamp: strings.TrimPrefix(lineSplit[0], "["),
|
|
|
|
}
|
|
|
|
|
|
|
|
return c.JSON(http.StatusOK, randomQ)
|
|
|
|
}
|
|
|
|
|
2017-03-08 21:38:01 +01:00
|
|
|
return c.String(http.StatusOK, lineSplit[1])
|
2017-03-11 21:51:08 +01:00
|
|
|
}
|
2018-12-02 14:53:01 +01:00
|
|
|
|
2018-12-02 19:23:54 +01:00
|
|
|
func (s *Server) getUserLogsByName(c echo.Context) error {
|
|
|
|
channel := strings.ToLower(c.Param("channel"))
|
|
|
|
username := strings.ToLower(c.Param("username"))
|
|
|
|
|
|
|
|
userMap, err := s.helixClient.GetUsersByUsernames([]string{channel, username})
|
|
|
|
if err != nil {
|
|
|
|
log.Error(err)
|
|
|
|
return c.JSON(http.StatusInternalServerError, "Failure fetching userIDs")
|
|
|
|
}
|
|
|
|
|
|
|
|
names := c.ParamNames()
|
|
|
|
names = append(names, "channelid")
|
|
|
|
names = append(names, "userid")
|
|
|
|
|
|
|
|
values := c.ParamValues()
|
|
|
|
values = append(values, userMap[channel].ID)
|
|
|
|
values = append(values, userMap[username].ID)
|
|
|
|
|
|
|
|
c.SetParamNames(names...)
|
|
|
|
c.SetParamValues(values...)
|
|
|
|
|
|
|
|
return s.getUserLogs(c)
|
|
|
|
}
|
|
|
|
|
2018-12-02 14:53:01 +01:00
|
|
|
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)
|
|
|
|
}
|