implement available logs endpoint for channels #173
This commit is contained in:
parent
7d00f66181
commit
8f0de04ec7
3 changed files with 91 additions and 3 deletions
|
@ -82,6 +82,11 @@ type logList struct {
|
||||||
AvailableLogs []filelog.UserLogFile `json:"availableLogs"`
|
AvailableLogs []filelog.UserLogFile `json:"availableLogs"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// swagger:model
|
||||||
|
type channelLogList struct {
|
||||||
|
AvailableLogs []filelog.ChannelLogFile `json:"availableLogs"`
|
||||||
|
}
|
||||||
|
|
||||||
type chatMessage struct {
|
type chatMessage struct {
|
||||||
Text string `json:"text"`
|
Text string `json:"text"`
|
||||||
Username string `json:"username"`
|
Username string `json:"username"`
|
||||||
|
|
21
api/user.go
21
api/user.go
|
@ -75,7 +75,7 @@ func (s *Server) getRandomQuote(request logRequest) (*chatLog, error) {
|
||||||
|
|
||||||
// swagger:route GET /list logs list
|
// swagger:route GET /list logs list
|
||||||
//
|
//
|
||||||
// Lists available logs of a user
|
// Lists available logs of a user or channel, channel response also includes the day. OpenAPI 2 does not support multiple responses with the same http code right now.
|
||||||
//
|
//
|
||||||
// Produces:
|
// Produces:
|
||||||
// - application/json
|
// - application/json
|
||||||
|
@ -86,9 +86,24 @@ func (s *Server) getRandomQuote(request logRequest) (*chatLog, error) {
|
||||||
// Responses:
|
// Responses:
|
||||||
// 200: logList
|
// 200: logList
|
||||||
func (s *Server) writeAvailableLogs(w http.ResponseWriter, r *http.Request, q url.Values) {
|
func (s *Server) writeAvailableLogs(w http.ResponseWriter, r *http.Request, q url.Values) {
|
||||||
logs, err := s.fileLogger.GetAvailableLogsForUser(q.Get("channelid"), q.Get("userid"))
|
channelid := q.Get("channelid")
|
||||||
|
userid := q.Get("userid")
|
||||||
|
|
||||||
|
if userid == "" {
|
||||||
|
logs, err := s.fileLogger.GetAvailableLogsForChannel(channelid)
|
||||||
|
if err != nil {
|
||||||
|
http.Error(w, "failed to get available channel logs: "+err.Error(), http.StatusNotFound)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
writeCacheControl(w, r, time.Hour)
|
||||||
|
writeJSON(&channelLogList{logs}, http.StatusOK, w, r)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
logs, err := s.fileLogger.GetAvailableLogsForUser(channelid, userid)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
http.Error(w, "failed to get available logs: "+err.Error(), http.StatusNotFound)
|
http.Error(w, "failed to get available user logs: "+err.Error(), http.StatusNotFound)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -194,6 +194,74 @@ func (l *Logger) GetAvailableLogsForUser(channelID, userID string) ([]UserLogFil
|
||||||
return logFiles, errors.New("No logs file")
|
return logFiles, errors.New("No logs file")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type ChannelLogFile struct {
|
||||||
|
path string
|
||||||
|
Year string `json:"year"`
|
||||||
|
Month string `json:"month"`
|
||||||
|
Day string `json:"day"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l *Logger) GetAvailableLogsForChannel(channelID string) ([]ChannelLogFile, error) {
|
||||||
|
if channelID == "" {
|
||||||
|
return []ChannelLogFile{}, fmt.Errorf("Invalid channelID: %s", channelID)
|
||||||
|
}
|
||||||
|
|
||||||
|
logFiles := []ChannelLogFile{}
|
||||||
|
|
||||||
|
years, _ := ioutil.ReadDir(l.logPath + "/" + channelID)
|
||||||
|
|
||||||
|
for _, yearDir := range years {
|
||||||
|
year := yearDir.Name()
|
||||||
|
months, _ := ioutil.ReadDir(l.logPath + "/" + channelID + "/" + year + "/")
|
||||||
|
for _, monthDir := range months {
|
||||||
|
month := monthDir.Name()
|
||||||
|
|
||||||
|
days, _ := ioutil.ReadDir(l.logPath + "/" + channelID + "/" + year + "/" + month + "/")
|
||||||
|
for _, dayDir := range days {
|
||||||
|
day := dayDir.Name()
|
||||||
|
path := fmt.Sprintf("%s/%s/%s/%s/%s/channel.txt", l.logPath, channelID, year, month, day)
|
||||||
|
|
||||||
|
if _, err := os.Stat(path); err == nil {
|
||||||
|
logFile := ChannelLogFile{path, year, month, day}
|
||||||
|
logFiles = append(logFiles, logFile)
|
||||||
|
} else if _, err := os.Stat(path + ".gz"); err == nil {
|
||||||
|
logFile := ChannelLogFile{path + ".gz", year, month, day}
|
||||||
|
logFiles = append(logFiles, logFile)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sort.Slice(logFiles, func(i, j int) bool {
|
||||||
|
yearA, _ := strconv.Atoi(logFiles[i].Year)
|
||||||
|
yearB, _ := strconv.Atoi(logFiles[j].Year)
|
||||||
|
monthA, _ := strconv.Atoi(logFiles[i].Month)
|
||||||
|
monthB, _ := strconv.Atoi(logFiles[j].Month)
|
||||||
|
dayA, _ := strconv.Atoi(logFiles[j].Day)
|
||||||
|
dayB, _ := strconv.Atoi(logFiles[j].Day)
|
||||||
|
|
||||||
|
if yearA == yearB {
|
||||||
|
if monthA == monthB {
|
||||||
|
return dayA > dayB
|
||||||
|
}
|
||||||
|
|
||||||
|
return monthA > monthB
|
||||||
|
}
|
||||||
|
|
||||||
|
if monthA == monthB {
|
||||||
|
return dayA > dayB
|
||||||
|
}
|
||||||
|
|
||||||
|
return yearA > yearB
|
||||||
|
})
|
||||||
|
|
||||||
|
if len(logFiles) > 0 {
|
||||||
|
return logFiles, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return logFiles, errors.New("No logs file")
|
||||||
|
}
|
||||||
|
|
||||||
// ReadLogForUser fetch logs
|
// ReadLogForUser fetch logs
|
||||||
func (l *Logger) ReadLogForUser(channelID, userID string, year string, month string) ([]string, error) {
|
func (l *Logger) ReadLogForUser(channelID, userID string, year string, month string) ([]string, error) {
|
||||||
if channelID == "" || userID == "" {
|
if channelID == "" || userID == "" {
|
||||||
|
|
Loading…
Add table
Reference in a new issue