You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
92 lines
2.3 KiB
92 lines
2.3 KiB
package mirclike
|
|
|
|
import (
|
|
"errors"
|
|
"strconv"
|
|
"strings"
|
|
"time"
|
|
|
|
"git.aiterp.net/rpdata/api/models"
|
|
)
|
|
|
|
// ErrNotPost is returned by parsePost if the line is empty or not a post.
|
|
var ErrNotPost = errors.New("not a post")
|
|
|
|
// ParsePost parses a post from a mirc-like line. If the previous post is included (it can be empty), it will be used
|
|
// to determine whether midnight has passed.
|
|
func ParsePost(line string, date time.Time, prev models.Post) (models.Post, error) {
|
|
// Do basic validation
|
|
line = strings.Trim(line, " \t\n\r")
|
|
if len(line) == 0 || !strings.HasPrefix(line, "[") {
|
|
return models.Post{}, ErrNotPost
|
|
}
|
|
|
|
// Parse timestamp
|
|
tsEndIndex := strings.IndexByte(line, ']')
|
|
if tsEndIndex == -1 || len(line) < tsEndIndex+5 {
|
|
return models.Post{}, ErrNotPost
|
|
}
|
|
tsStr := line[1:tsEndIndex]
|
|
tsSplit := strings.Split(tsStr, ":")
|
|
tsUnits := make([]int, len(tsSplit))
|
|
if len(tsSplit) < 2 {
|
|
return models.Post{}, ErrNotPost
|
|
}
|
|
for i := range tsSplit {
|
|
n, err := strconv.Atoi(tsSplit[i])
|
|
if err != nil {
|
|
return models.Post{}, ErrNotPost
|
|
}
|
|
|
|
tsUnits[i] = n
|
|
}
|
|
if len(tsUnits) == 2 {
|
|
tsUnits = append(tsUnits, 0)
|
|
}
|
|
|
|
// Determine timestamp from parsed data and previous post.
|
|
ts := time.Date(date.Year(), date.Month(), date.Day(), tsUnits[0], tsUnits[1], tsUnits[2], 0, date.Location())
|
|
if !prev.Time.IsZero() && prev.Time.Sub(ts) > 30*time.Minute {
|
|
ts = time.Date(prev.Time.Year(), prev.Time.Month(), prev.Time.Day()+1, tsUnits[0], tsUnits[1], tsUnits[2], 0, date.Location())
|
|
}
|
|
|
|
if line[tsEndIndex+2] == '*' {
|
|
split := strings.SplitN(line[tsEndIndex+4:], " ", 2)
|
|
|
|
post := models.Post{
|
|
ID: "UNASSIGNED",
|
|
LogID: "UNASSIGNED",
|
|
Time: ts,
|
|
Kind: "action",
|
|
Nick: strings.TrimLeft(split[0], "+@!~"),
|
|
Text: split[1],
|
|
Position: prev.Position + 1,
|
|
}
|
|
|
|
if post.Nick[0] == '=' {
|
|
post.Kind = "scene"
|
|
}
|
|
|
|
return post, nil
|
|
} else if line[tsEndIndex+2] == '<' {
|
|
split := strings.SplitN(line[tsEndIndex+2:], " ", 2)
|
|
|
|
post := models.Post{
|
|
ID: "UNASSIGNED",
|
|
LogID: "UNASSIGNED",
|
|
Time: ts,
|
|
Kind: "text",
|
|
Nick: strings.TrimLeft(split[0][1:len(split[0])-1], "+@!~"),
|
|
Text: split[1],
|
|
Position: prev.Position + 1,
|
|
}
|
|
|
|
if post.Nick[0] == '=' {
|
|
post.Kind = "scene"
|
|
}
|
|
|
|
return post, nil
|
|
} else {
|
|
return models.Post{}, ErrNotPost
|
|
}
|
|
}
|