Support vCard4 via PubSub

This commit is contained in:
Bohdan Horbeshko 2022-06-28 19:34:14 -04:00
parent 3a43c6223f
commit 76ac662366
2 changed files with 129 additions and 12 deletions

View file

@ -119,7 +119,7 @@ func (c IqVcardTemp) Namespace() string {
return c.XMLName.Space
}
// Namespace is a namespace!
// GetSet getsets!
func (c IqVcardTemp) GetSet() *stanza.ResultSet {
return c.ResultSet
}

View file

@ -3,6 +3,7 @@ package xmpp
import (
"bytes"
"encoding/base64"
"encoding/xml"
"github.com/pkg/errors"
"io"
"strconv"
@ -17,6 +18,12 @@ import (
"gosrc.io/xmpp/stanza"
)
const (
TypeVCardTemp byte = iota
TypeVCard4
)
const NodeVCard4 string = "urn:xmpp:vcard4"
func logPacketType(p stanza.Packet) {
log.Warnf("Ignoring packet: %T\n", p)
}
@ -33,9 +40,16 @@ func HandleIq(s xmpp.Sender, p stanza.Packet) {
if iq.Type == "get" {
_, ok := iq.Payload.(*extensions.IqVcardTemp)
if ok {
go handleGetVcardTempIq(s, iq)
go handleGetVcardIq(s, iq, TypeVCardTemp)
return
}
pubsub, ok := iq.Payload.(*stanza.PubSubGeneric)
if ok {
if pubsub.Items != nil && pubsub.Items.Node == NodeVCard4 {
go handleGetVcardIq(s, iq, TypeVCard4)
return
}
}
_, ok = iq.Payload.(*stanza.DiscoInfo)
if ok {
go handleGetDiscoInfo(s, iq)
@ -216,7 +230,7 @@ func handlePresence(s xmpp.Sender, p stanza.Presence) {
}
}
func handleGetVcardTempIq(s xmpp.Sender, iq *stanza.IQ) {
func handleGetVcardIq(s xmpp.Sender, iq *stanza.IQ, typ byte) {
log.WithFields(log.Fields{
"from": iq.From,
"to": iq.To,
@ -246,9 +260,9 @@ func handleGetVcardTempIq(s xmpp.Sender, iq *stanza.IQ) {
return
}
vcard := extensions.IqVcardTemp{}
var fn, photo, nickname, given, family, tel string
if chat != nil {
vcard.Fn.Text = chat.Title
fn = chat.Title
if chat.Photo != nil {
file, path, err := session.OpenPhotoFile(chat.Photo.Small, 32)
@ -260,8 +274,7 @@ func handleGetVcardTempIq(s xmpp.Sender, iq *stanza.IQ) {
_, err = io.Copy(binval, file)
binval.Close()
if err == nil {
vcard.Photo.Type.Text = "image/jpeg"
vcard.Photo.Binval.Text = buf.String()
photo = buf.String()
} else {
log.Errorf("Error calculating base64: %v", path)
}
@ -273,10 +286,10 @@ func handleGetVcardTempIq(s xmpp.Sender, iq *stanza.IQ) {
}
}
if user != nil {
vcard.Nickname.Text = user.Username
vcard.N.Given.Text = user.FirstName
vcard.N.Family.Text = user.LastName
vcard.Tel.Number.Text = user.PhoneNumber
nickname = user.Username
given = user.FirstName
family = user.LastName
tel = user.PhoneNumber
}
answer := stanza.IQ{
@ -286,7 +299,7 @@ func handleGetVcardTempIq(s xmpp.Sender, iq *stanza.IQ) {
Id: iq.Id,
Type: "result",
},
Payload: vcard,
Payload: makeVCardPayload(typ, iq.To, fn, photo, nickname, given, family, tel),
}
log.Debugf("%#v", answer)
@ -357,3 +370,107 @@ func toToID(to string) (int64, bool) {
}
return toID, true
}
func makeVCardPayload(typ byte, id string, fn string, photo string, nickname string, given string, family string, tel string) stanza.IQPayload {
if typ == TypeVCardTemp {
vcard := &extensions.IqVcardTemp{}
vcard.Fn.Text = fn
if photo != "" {
vcard.Photo.Type.Text = "image/jpeg"
vcard.Photo.Binval.Text = photo
}
vcard.Nickname.Text = nickname
vcard.N.Given.Text = given
vcard.N.Family.Text = family
vcard.Tel.Number.Text = tel
return vcard
} else if typ == TypeVCard4 {
nodes := []stanza.Node{}
if fn != "" {
nodes = append(nodes, stanza.Node{
XMLName: xml.Name{Local: "fn"},
Nodes: []stanza.Node{
stanza.Node{
XMLName: xml.Name{Local: "text"},
Content: fn,
},
},
})
}
if photo != "" {
nodes = append(nodes, stanza.Node{
XMLName: xml.Name{Local: "photo"},
Nodes: []stanza.Node{
stanza.Node{
XMLName: xml.Name{Local: "uri"},
Content: "data:image/jpeg;base64," + photo,
},
},
})
}
if nickname != "" {
nodes = append(nodes, stanza.Node{
XMLName: xml.Name{Local: "nickname"},
Nodes: []stanza.Node{
stanza.Node{
XMLName: xml.Name{Local: "text"},
Content: nickname,
},
},
})
}
if family != "" || given != "" {
nodes = append(nodes, stanza.Node{
XMLName: xml.Name{Local: "n"},
Nodes: []stanza.Node{
stanza.Node{
XMLName: xml.Name{Local: "surname"},
Content: family,
},
stanza.Node{
XMLName: xml.Name{Local: "given"},
Content: given,
},
},
})
}
if tel != "" {
nodes = append(nodes, stanza.Node{
XMLName: xml.Name{Local: "tel"},
Nodes: []stanza.Node{
stanza.Node{
XMLName: xml.Name{Local: "uri"},
Content: "tel:" + tel,
},
},
})
}
pubsub := &stanza.PubSubGeneric{
Items: &stanza.Items{
Node: NodeVCard4,
List: []stanza.Item{
stanza.Item{
Id: id,
Any: &stanza.Node{
XMLName: xml.Name{Local: "vcard"},
Attrs: []xml.Attr{
xml.Attr{
Name: xml.Name{Local: "xmlns"},
Value: "urn:ietf:params:xml:ns:vcard-4.0",
},
},
Nodes: nodes,
},
},
},
},
}
return pubsub
}
return nil
}