Refactoring: move SendPresence to xmpp/gateway package

This commit is contained in:
bodqhrohro 2019-11-25 00:20:07 +02:00
parent 653b1bde94
commit d6f6207ebb
5 changed files with 124 additions and 116 deletions

View file

@ -4,7 +4,7 @@ all:
go build -o telegabber go build -o telegabber
test: test:
go test -v ./config ./ ./telegram ./xmpp go test -v ./config ./ ./telegram ./xmpp/gateway
lint: lint:
$(GOPATH)/bin/golint ./... $(GOPATH)/bin/golint ./...

View file

@ -1,7 +1,6 @@
package xmpp package xmpp
import ( import (
"encoding/xml"
"github.com/pkg/errors" "github.com/pkg/errors"
"time" "time"
@ -11,16 +10,14 @@ import (
"dev.narayana.im/narayana/telegabber/xmpp/gateway" "dev.narayana.im/narayana/telegabber/xmpp/gateway"
log "github.com/sirupsen/logrus" log "github.com/sirupsen/logrus"
"github.com/soheilhy/args"
"gosrc.io/xmpp" "gosrc.io/xmpp"
"gosrc.io/xmpp/stanza"
) )
const pollingInterval time.Duration = 1e7 const pollingInterval time.Duration = 1e7
var tgConf config.TelegramConfig var tgConf config.TelegramConfig
var sessions map[string]*telegram.Client var sessions map[string]*telegram.Client
var queue map[string]*stanza.Presence var queue gateway.Queue
var db persistence.SessionsYamlDB var db persistence.SessionsYamlDB
// NewComponent starts a new component and wraps it in // NewComponent starts a new component and wraps it in
@ -33,6 +30,8 @@ func NewComponent(conf config.XMPPConfig, tc config.TelegramConfig) (*xmpp.Strea
return nil, nil, err return nil, nil, err
} }
queue = make(gateway.Queue)
tgConf = tc tgConf = tc
options := xmpp.ComponentOptions{ options := xmpp.ComponentOptions{
@ -64,19 +63,13 @@ func NewComponent(conf config.XMPPConfig, tc config.TelegramConfig) (*xmpp.Strea
return sm, component, nil return sm, component, nil
} }
func logPresence(err error, presence *stanza.Presence) {
log.WithFields(log.Fields{
"presence": *presence,
}).Error(errors.Wrap(err, "Couldn't send presence"))
}
func heartbeat(component *xmpp.Component) { func heartbeat(component *xmpp.Component) {
var err error var err error
probeType := SPType("probe") probeType := gateway.SPType("probe")
for jid := range sessions { for jid := range sessions {
for { for {
err = sendPresence(component, jid, probeType) err = gateway.SendPresence(component, queue, jid, probeType)
if err == nil { if err == nil {
break break
} }
@ -90,7 +83,7 @@ func heartbeat(component *xmpp.Component) {
for key, presence := range queue { for key, presence := range queue {
err = component.Send(presence) err = component.Send(presence)
if err != nil { if err != nil {
logPresence(err, presence) gateway.LogBadPresence(err, presence)
} else { } else {
delete(queue, key) delete(queue, key)
} }
@ -135,106 +128,6 @@ func getTelegramInstance(jid string, savedSession *persistence.Session, componen
return session, true return session, true
} }
// SPFrom is a Telegram user id
var SPFrom = args.NewString()
// SPType is a presence type
var SPType = args.NewString()
// SPShow is a availability status
var SPShow = args.NewString()
// SPStatus is a verbose status
var SPStatus = args.NewString()
// SPNickname is a XEP-0172 nickname
var SPNickname = args.NewString()
// SPPhoto is a XEP-0153 hash of avatar in vCard
var SPPhoto = args.NewString()
// SPImmed skips queueing
var SPImmed = args.NewBool(args.Default(true))
func newPresence(bareJid string, to string, args ...args.V) stanza.Presence {
var presenceFrom string
if SPFrom.IsSet(args) {
presenceFrom = SPFrom.Get(args) + "@" + bareJid
} else {
presenceFrom = bareJid
}
presence := stanza.Presence{Attrs: stanza.Attrs{
From: presenceFrom,
To: to,
}}
if SPType.IsSet(args) {
presence.Attrs.Type = stanza.StanzaType(SPType.Get(args))
}
if SPShow.IsSet(args) {
presence.Show = stanza.PresenceShow(SPShow.Get(args))
}
if SPStatus.IsSet(args) {
presence.Status = SPStatus.Get(args)
}
if SPNickname.IsSet(args) {
presence.Extensions = append(presence.Extensions, PresenceNickExtension{
Text: SPNickname.Get(args),
})
}
if SPPhoto.IsSet(args) {
presence.Extensions = append(presence.Extensions, PresenceXVCardUpdateExtension{
Photo: PresenceXVCardUpdatePhoto{
Text: SPPhoto.Get(args),
},
})
}
return presence
}
func sendPresence(component *xmpp.Component, to string, args ...args.V) error {
var logFrom string
bareJid := gateway.Jid.Bare()
if SPFrom.IsSet(args) {
logFrom = SPFrom.Get(args)
} else {
logFrom = bareJid
}
log.WithFields(log.Fields{
"type": SPType.Get(args),
"from": logFrom,
"to": to,
}).Info("Got presence")
presence := newPresence(bareJid, to, args...)
// explicit check, as marshalling is expensive
if log.GetLevel() == log.DebugLevel {
xmlPresence, err := xml.Marshal(presence)
if err == nil {
log.Debug(string(xmlPresence))
} else {
log.Debugf("%#v", presence)
}
}
immed := SPImmed.Get(args)
if immed {
err := component.Send(presence)
if err != nil {
logPresence(err, &presence)
return err
}
} else {
queue[presence.From+presence.To] = &presence
}
return nil
}
// Close gracefully terminates the component and saves active sessions // Close gracefully terminates the component and saves active sessions
func Close(component *xmpp.Component) { func Close(component *xmpp.Component) {
log.Error("Disconnecting...") log.Error("Disconnecting...")

View file

@ -1,4 +1,4 @@
package xmpp package extensions
import ( import (
"encoding/xml" "encoding/xml"

View file

@ -2,12 +2,19 @@ package gateway
import ( import (
"encoding/xml" "encoding/xml"
"github.com/pkg/errors"
"dev.narayana.im/narayana/telegabber/xmpp/extensions"
log "github.com/sirupsen/logrus" log "github.com/sirupsen/logrus"
"github.com/soheilhy/args"
"gosrc.io/xmpp" "gosrc.io/xmpp"
"gosrc.io/xmpp/stanza" "gosrc.io/xmpp/stanza"
) )
// Queue stores presences to send later
type Queue map[string]*stanza.Presence
// Jid stores the component's JID object // Jid stores the component's JID object
var Jid *xmpp.Jid var Jid *xmpp.Jid
@ -51,3 +58,111 @@ func SendMessage(to string, from string, body string, component *xmpp.Component)
_ = component.Send(message) _ = component.Send(message)
} }
// LogBadPresence verbosely logs a presence
func LogBadPresence(err error, presence *stanza.Presence) {
log.WithFields(log.Fields{
"presence": *presence,
}).Error(errors.Wrap(err, "Couldn't send presence"))
}
// SPFrom is a Telegram user id
var SPFrom = args.NewString()
// SPType is a presence type
var SPType = args.NewString()
// SPShow is a availability status
var SPShow = args.NewString()
// SPStatus is a verbose status
var SPStatus = args.NewString()
// SPNickname is a XEP-0172 nickname
var SPNickname = args.NewString()
// SPPhoto is a XEP-0153 hash of avatar in vCard
var SPPhoto = args.NewString()
// SPImmed skips queueing
var SPImmed = args.NewBool(args.Default(true))
func newPresence(bareJid string, to string, args ...args.V) stanza.Presence {
var presenceFrom string
if SPFrom.IsSet(args) {
presenceFrom = SPFrom.Get(args) + "@" + bareJid
} else {
presenceFrom = bareJid
}
presence := stanza.Presence{Attrs: stanza.Attrs{
From: presenceFrom,
To: to,
}}
if SPType.IsSet(args) {
presence.Attrs.Type = stanza.StanzaType(SPType.Get(args))
}
if SPShow.IsSet(args) {
presence.Show = stanza.PresenceShow(SPShow.Get(args))
}
if SPStatus.IsSet(args) {
presence.Status = SPStatus.Get(args)
}
if SPNickname.IsSet(args) {
presence.Extensions = append(presence.Extensions, extensions.PresenceNickExtension{
Text: SPNickname.Get(args),
})
}
if SPPhoto.IsSet(args) {
presence.Extensions = append(presence.Extensions, extensions.PresenceXVCardUpdateExtension{
Photo: extensions.PresenceXVCardUpdatePhoto{
Text: SPPhoto.Get(args),
},
})
}
return presence
}
// SendPresence creates and sends a presence stanza
func SendPresence(component *xmpp.Component, queue Queue, to string, args ...args.V) error {
var logFrom string
bareJid := Jid.Bare()
if SPFrom.IsSet(args) {
logFrom = SPFrom.Get(args)
} else {
logFrom = bareJid
}
log.WithFields(log.Fields{
"type": SPType.Get(args),
"from": logFrom,
"to": to,
}).Info("Got presence")
presence := newPresence(bareJid, to, args...)
// explicit check, as marshalling is expensive
if log.GetLevel() == log.DebugLevel {
xmlPresence, err := xml.Marshal(presence)
if err == nil {
log.Debug(string(xmlPresence))
} else {
log.Debugf("%#v", presence)
}
}
immed := SPImmed.Get(args)
if immed {
err := component.Send(presence)
if err != nil {
LogBadPresence(err, &presence)
return err
}
} else {
queue[presence.From+presence.To] = &presence
}
return nil
}

View file

@ -1,4 +1,4 @@
package xmpp package gateway
import ( import (
"encoding/xml" "encoding/xml"