summaryrefslogtreecommitdiff
path: root/irc
diff options
context:
space:
mode:
Diffstat (limited to 'irc')
-rw-r--r--irc/events.go4
-rw-r--r--irc/session.go60
-rw-r--r--irc/tokens.go28
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, &timestamp); 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