diff options
Diffstat (limited to 'irc')
-rw-r--r-- | irc/events.go | 4 | ||||
-rw-r--r-- | irc/session.go | 60 | ||||
-rw-r--r-- | irc/tokens.go | 28 |
3 files changed, 63 insertions, 29 deletions
diff --git a/irc/events.go b/irc/events.go index c90f518..70a6c1d 100644 --- a/irc/events.go +++ b/irc/events.go @@ -76,6 +76,10 @@ type HistoryEvent struct { Messages []Event } +type HistoryTargetsEvent struct { + Targets map[string]time.Time +} + type BouncerNetworkEvent struct { ID string Name string diff --git a/irc/session.go b/irc/session.go index 7e1c664..8467f2c 100644 --- a/irc/session.go +++ b/irc/session.go @@ -124,10 +124,12 @@ type Session struct { prefixSymbols string prefixModes string - users map[string]*User // known users. - channels map[string]Channel // joined channels. - chBatches map[string]HistoryEvent // channel history batches being processed. - chReqs map[string]struct{} // set of targets for which history is currently requested. + users map[string]*User // known users. + channels map[string]Channel // joined channels. + chBatches map[string]HistoryEvent // channel history batches being processed. + chReqs map[string]struct{} // set of targets for which history is currently requested. + targetsBatchID string // ID of the channel history targets batch being processed. + targetsBatch HistoryTargetsEvent // channel history targets batch being processed. pendingChannels map[string]time.Time // set of join requests stamps for channels. } @@ -228,16 +230,16 @@ func (s *Session) Names(target string) []Member { names = make([]Member, 0, len(c.Members)) for u, pl := range c.Members { names = append(names, Member{ - PowerLevel: pl, - Name: u.Name.Copy(), - Away: u.Away, + PowerLevel: pl, + Name: u.Name.Copy(), + Away: u.Away, }) } } } else if u, ok := s.users[s.Casemap(target)]; ok { names = append(names, Member{ - Name: u.Name.Copy(), - Away: u.Away, + Name: u.Name.Copy(), + Away: u.Away, }) names = append(names, Member{ Name: &Prefix{ @@ -448,7 +450,9 @@ func (r *HistoryRequest) doRequest() { args := make([]string, 0, len(r.bounds)+3) args = append(args, r.command) - args = append(args, r.target) + if r.target != "" { + args = append(args, r.target) + } args = append(args, r.bounds...) args = append(args, strconv.Itoa(r.limit)) r.s.out <- NewMessage("CHATHISTORY", args...) @@ -466,6 +470,13 @@ func (r *HistoryRequest) Before(t time.Time) { r.doRequest() } +func (r *HistoryRequest) Targets(start time.Time, end time.Time) { + r.command = "TARGETS" + r.bounds = []string{formatTimestamp(start), formatTimestamp(end)} + r.target = "" + r.doRequest() +} + func (s *Session) NewHistoryRequest(target string) *HistoryRequest { return &HistoryRequest{ s: s, @@ -505,7 +516,17 @@ func (s *Session) handleUnregistered(msg Message) (Event, error) { func (s *Session) handleRegistered(msg Message) (Event, error) { if id, ok := msg.Tags["batch"]; ok { - if b, ok := s.chBatches[id]; ok { + if id == s.targetsBatchID { + var target, timestamp string + if err := msg.ParseParams(nil, &target, ×tamp); err != nil { + return nil, err + } + t, ok := parseTimestamp(timestamp) + if !ok { + return nil, nil + } + s.targetsBatch.Targets[target] = t + } else if b, ok := s.chBatches[id]; ok { ev, err := s.newMessageEvent(msg) if err != nil { return nil, err @@ -1002,11 +1023,20 @@ func (s *Session) handleRegistered(msg Message) (Event, error) { } s.chBatches[id] = HistoryEvent{Target: target} + case "draft/chathistory-targets": + s.targetsBatchID = id + s.targetsBatch = HistoryTargetsEvent{Targets: make(map[string]time.Time)} + } + } else { + if b, ok := s.chBatches[id]; ok { + delete(s.chBatches, id) + delete(s.chReqs, s.Casemap(b.Target)) + return b, nil + } else if s.targetsBatchID == id { + s.targetsBatchID = "" + delete(s.chReqs, "") + return s.targetsBatch, nil } - } else if b, ok := s.chBatches[id]; ok { - delete(s.chBatches, id) - delete(s.chReqs, s.Casemap(b.Target)) - return b, nil } case "NICK": if msg.Prefix == nil { diff --git a/irc/tokens.go b/irc/tokens.go index b28ef12..ab7b418 100644 --- a/irc/tokens.go +++ b/irc/tokens.go @@ -360,26 +360,26 @@ func (msg *Message) ParseParams(out ...*string) error { return nil } -// Time returns the time when the message has been sent, if present. -func (msg *Message) Time() (t time.Time, ok bool) { - var tag string +func parseTimestamp(timestamp string) (time.Time, bool) { var year, month, day, hour, minute, second, millis int - tag, ok = msg.Tags["time"] - if !ok { - return - } - - tag = strings.TrimSuffix(tag, "Z") + timestamp = strings.TrimSuffix(timestamp, "Z") - _, err := fmt.Sscanf(tag, "%4d-%2d-%2dT%2d:%2d:%2d.%3d", &year, &month, &day, &hour, &minute, &second, &millis) + _, err := fmt.Sscanf(timestamp, "%4d-%2d-%2dT%2d:%2d:%2d.%3d", &year, &month, &day, &hour, &minute, &second, &millis) if err != nil || month < 1 || 12 < month { - ok = false - return + return time.Time{}, false } - t = time.Date(year, time.Month(month), day, hour, minute, second, millis*1e6, time.UTC) - return + return time.Date(year, time.Month(month), day, hour, minute, second, millis*1e6, time.UTC), true +} + +// Time returns the time when the message has been sent, if present. +func (msg *Message) Time() (t time.Time, ok bool) { + tag, ok := msg.Tags["time"] + if !ok { + return time.Time{}, false + } + return parseTimestamp(tag) } // TimeOrNow returns the time when the message has been sent, or time.Now() if |