# HG changeset patch # User Chris Jones # Date 1325471571 25200 # Node ID 4a4530b8f62235647f8e720e2075ffc75682f587 # Parent abf958bcc201774e9cabb0bc5d744f8c02289bf7 Added roster updating. diff -r abf958bcc201 -r 4a4530b8f622 roster.go --- a/roster.go Sun Jan 01 19:00:21 2012 -0700 +++ b/roster.go Sun Jan 01 19:32:51 2012 -0700 @@ -62,8 +62,6 @@ return <- ch } -// BUG(cjyar) The roster isn't actually updated when things change. - // Returns the current roster of other entities which this one has a // relationship with. Changes to the roster will be signaled by an // appropriate Iq appearing on Client.In. See RFC 3921, Section 7.4. @@ -74,3 +72,40 @@ } return r } + +// The roster filter updates the Client's representation of the +// roster, but it lets the relevant stanzas through. +func (cl *Client) startRosterFilter() { + out := make(chan Stanza) + in := cl.AddFilter(out) + go func(inSave <-chan Stanza, outSave chan<- Stanza) { + defer close(out) + in := inSave + var out chan<- Stanza + var st Stanza + var ok bool + for { + select { + case st, ok = <- in: + if !ok { + break + } + cl.maybeUpdateRoster(st) + in = nil + out = outSave + case out <- st: + out = nil + in = inSave + } + } + }(in, out) +} + +func (cl *Client) maybeUpdateRoster(st Stanza) { + rq, ok := st.GetNested().(*RosterQuery) + if st.GetName() == "iq" && st.GetType() == "set" && ok { + for _, item := range(rq.Item) { + cl.roster[item.Jid] = &item + } + } +} diff -r abf958bcc201 -r 4a4530b8f622 stream.go --- a/stream.go Sun Jan 01 19:00:21 2012 -0700 +++ b/stream.go Sun Jan 01 19:32:51 2012 -0700 @@ -217,8 +217,6 @@ } } -// BUG(cjyar) Allow extensions to provide filters in the form of "in -// chan<- Stanza, out <-chan Stanza". func (cl *Client) readStream(srvIn <-chan interface{}, cliOut chan<- Stanza) { defer tryClose(srvIn, cliOut) diff -r abf958bcc201 -r 4a4530b8f622 xmpp.go --- a/xmpp.go Sun Jan 01 19:00:21 2012 -0700 +++ b/xmpp.go Sun Jan 01 19:32:51 2012 -0700 @@ -146,6 +146,7 @@ // Start the manager for the filters that can modify what the // app sees. clIn := cl.startFilter(stIn) + cl.startRosterFilter() // Initial handshake. hsOut := &stream{To: jid.Domain, Version: Version} @@ -200,6 +201,8 @@ filterOut := make(chan (<-chan Stanza)) filterIn := make(chan (<-chan Stanza)) go filter(srvIn, cliOut, filterOut, filterIn) + cl.filterOut = filterOut + cl.filterIn = filterIn return cliOut }