Introduce loadHistoryLatestID
This loads latest messages from logs up to a given message ID. This is
similar to the IRCv3 CHATHISTORY LATEST command [1].
[1]: 0c271a5f1d/extensions/chathistory.md (latest)
This commit is contained in:
parent
8f29ae41a2
commit
b6f15c3e3c
60
logger.go
60
logger.go
@ -233,7 +233,7 @@ func parseMessage(line, entity string, ref time.Time) (*irc.Message, time.Time,
|
|||||||
return msg, t, nil
|
return msg, t, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func parseMessagesBefore(network *network, entity string, ref time.Time, limit int) ([]*irc.Message, error) {
|
func parseMessagesBefore(network *network, entity string, ref time.Time, limit int, afterOffset int64) ([]*irc.Message, error) {
|
||||||
path := logPath(network, entity, ref)
|
path := logPath(network, entity, ref)
|
||||||
f, err := os.Open(path)
|
f, err := os.Open(path)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -248,6 +248,14 @@ func parseMessagesBefore(network *network, entity string, ref time.Time, limit i
|
|||||||
cur := 0
|
cur := 0
|
||||||
|
|
||||||
sc := bufio.NewScanner(f)
|
sc := bufio.NewScanner(f)
|
||||||
|
|
||||||
|
if afterOffset >= 0 {
|
||||||
|
if _, err := f.Seek(afterOffset, io.SeekStart); err != nil {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
sc.Scan() // skip till next newline
|
||||||
|
}
|
||||||
|
|
||||||
for sc.Scan() {
|
for sc.Scan() {
|
||||||
msg, t, err := parseMessage(sc.Text(), entity, ref)
|
msg, t, err := parseMessage(sc.Text(), entity, ref)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -316,7 +324,7 @@ func loadHistoryBeforeTime(network *network, entity string, t time.Time, limit i
|
|||||||
remaining := limit
|
remaining := limit
|
||||||
tries := 0
|
tries := 0
|
||||||
for remaining > 0 && tries < messageLoggerMaxTries {
|
for remaining > 0 && tries < messageLoggerMaxTries {
|
||||||
buf, err := parseMessagesBefore(network, entity, t, remaining)
|
buf, err := parseMessagesBefore(network, entity, t, remaining, -1)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -356,3 +364,51 @@ func loadHistoryAfterTime(network *network, entity string, t time.Time, limit in
|
|||||||
}
|
}
|
||||||
return history, nil
|
return history, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func truncateDay(t time.Time) time.Time {
|
||||||
|
year, month, day := t.Date()
|
||||||
|
return time.Date(year, month, day, 0, 0, 0, 0, t.Location())
|
||||||
|
}
|
||||||
|
|
||||||
|
func loadHistoryLatestID(network *network, entity, id string, limit int) ([]*irc.Message, error) {
|
||||||
|
var afterTime time.Time
|
||||||
|
var afterOffset int64
|
||||||
|
if id != "" {
|
||||||
|
var idNet, idEntity string
|
||||||
|
var err error
|
||||||
|
idNet, idEntity, afterTime, afterOffset, err = parseMsgID(id)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if idNet != network.GetName() || idEntity != entity {
|
||||||
|
return nil, fmt.Errorf("cannot find message ID: message ID doesn't match network/entity")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
history := make([]*irc.Message, limit)
|
||||||
|
t := time.Now()
|
||||||
|
remaining := limit
|
||||||
|
tries := 0
|
||||||
|
for remaining > 0 && tries < messageLoggerMaxTries && !truncateDay(t).Before(afterTime) {
|
||||||
|
var offset int64 = -1
|
||||||
|
if afterOffset >= 0 && truncateDay(t).Equal(afterTime) {
|
||||||
|
offset = afterOffset
|
||||||
|
}
|
||||||
|
|
||||||
|
buf, err := parseMessagesBefore(network, entity, t, remaining, offset)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if len(buf) == 0 {
|
||||||
|
tries++
|
||||||
|
} else {
|
||||||
|
tries = 0
|
||||||
|
}
|
||||||
|
copy(history[remaining-len(buf):], buf)
|
||||||
|
remaining -= len(buf)
|
||||||
|
year, month, day := t.Date()
|
||||||
|
t = time.Date(year, month, day, 0, 0, 0, 0, t.Location()).Add(-1)
|
||||||
|
}
|
||||||
|
|
||||||
|
return history[remaining:], nil
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user