import (
xmpp "code.google.com/p/goexmpp"
- "fmt"
"log"
"crypto/tls"
"os"
//~ log.Printf(fmt, v...)
//~ }
-func IfThenElseStr(c bool, strue, sfalse string) string {
- if c {return strue} else {return sfalse}
-}
func (botdata *XmppBot) makeXMPPMessage(to string, message interface{}, subject interface{}) *xmpp.Message {
xmppmsgheader := xmpp.Header{To: to,
return &xmpp.Message{Header: xmppmsgheader , Subject: msgsubject, Body: msgbody, Thread: &xmpp.Generic{}}
}
-func (botdata *XmppBot) makeXMPPPresence(to, ptype string) *xmpp.Presence {
+func (botdata *XmppBot) makeXMPPPresence(to, ptype, show, status string) *xmpp.Presence {
xmppmsgheader := xmpp.Header{To: to,
From: botdata.my_jid_,
Id: <-xmpp.Id,
Innerxml: "",
Error: nil,
Nested: make([]interface{},0)}
- return &xmpp.Presence{Header: xmppmsgheader}
+ var gen_show, gen_status *xmpp.Generic
+ if len(show) == 0 {
+ gen_show = nil
+ } else {
+ gen_show = &xmpp.Generic{Chardata: show}
+ }
+ if len(status) == 0 {
+ gen_status = nil
+ } else {
+ gen_status = &xmpp.Generic{Chardata: status}
+ }
+ return &xmpp.Presence{Header: xmppmsgheader, Show: gen_show, Status: gen_status}
}
type R3JIDDesire int
const (
R3NoChange R3JIDDesire = -1
- R3NoInfo R3JIDDesire = iota // ignore first value by assigning to blank identifier
- R3NoOfflineInfo
- R3AllInfo
+ R3NeverInfo R3JIDDesire = iota // ignore first value by assigning to blank identifier
+ R3OnlineOnlyInfo
+ R3OnlineOnlyWithRecapInfo
+ R3AlwaysInfo
R3DebugInfo
)
+const (
+ ShowOnline string = ""
+ ShowAway string = "away"
+ ShowNotAvailabe string = "xa"
+ ShowDoNotDisturb string = "dnd"
+ ShowFreeForChat string = "chat"
+)
+
type JidData struct {
Online bool
Wants R3JIDDesire
StatusNow bool
}
-type XMPPPresenceEvent struct {
- Present bool
- Who string
- DoorLock bool
- DoorShut bool
- Button bool
- Ts int64
+type XMPPMsgEvent struct {
+ Msg string
+ DistributeLevel R3JIDDesire
+ RememberAsStatus bool
+}
+
+type XMPPStatusEvent struct {
+ Show string
+ Status string
}
type RealraumXmppNotifierConfig map[string]JidData
//~ xmpp.Warn = logger
}
-func composeMessage(pec *XMPPPresenceEvent, both bool) *string {
- var msg string
- msg = ""
- if pec.Button {
- msg = "The button has been pressed ! Propably someone is bored and in need of company ! ;-)"
- if both { msg += "\n"; } else {
- msg += " --- " + time.Unix(pec.Ts,0).String()
- return &msg;
- }
- }
- msg += fmt.Sprintf("%s (Door is %s and %s and was last used by %s at %s)",
- IfThenElseStr(pec.Present, "Somebody is present!" , "Everybody left."),
- IfThenElseStr(pec.DoorLock, "locked","unlocked"),
- IfThenElseStr(pec.DoorShut, "shut","ajar"),
- pec.Who,
- time.Unix(pec.Ts,0).String())
- return &msg
-}
-
func (botdata *XmppBot) handleEventsforXMPP(xmppout chan <- xmpp.Stanza, presence_events <- chan interface{}, jabber_events <- chan JabberEvent) {
- var debug_msg bool
- var last_presence_event *XMPPPresenceEvent
- var msg *string
+ var last_status_msg *string
+
+ defer func() {
+ if x := recover(); x != nil {
+ log.Printf("handleEventsforXMPP: run time panic: %v", x)
+ }
+ }()
for {
- debug_msg = false
select {
case pe := <-presence_events:
switch pec := pe.(type) {
xmppout <- pec
continue
case string:
- msg = &pec
- debug_msg = true
- case XMPPPresenceEvent:
- debug_msg = last_presence_event != nil && last_presence_event.Present == pec.Present
- last_presence_event = &pec
- msg = composeMessage(last_presence_event, false)
- default:
- break
- }
-
- if msg == nil { continue }
-
- for to, jiddata := range botdata.realraum_jids_ {
- if debug_msg && jiddata.Wants < R3DebugInfo {
- continue
+ for to, jiddata := range botdata.realraum_jids_ {
+ if jiddata.Wants >= R3DebugInfo {
+ xmppout <- botdata.makeXMPPMessage(to, pec, nil)
+ }
+ }
+
+ case XMPPStatusEvent:
+ xmppout <- botdata.makeXMPPPresence("", "", pec.Show, pec.Status)
+
+ case XMPPMsgEvent:
+ if pec.RememberAsStatus {
+ last_status_msg = &pec.Msg
}
- if (jiddata.Wants == R3NoOfflineInfo && jiddata.Online) || jiddata.Wants > R3NoOfflineInfo {
- xmppout <- botdata.makeXMPPMessage(to, msg, nil)
+ for to, jiddata := range botdata.realraum_jids_ {
+ if jiddata.Wants >= pec.DistributeLevel && ((jiddata.Wants >= R3OnlineOnlyInfo && jiddata.Online) || jiddata.Wants >= R3AlwaysInfo) {
+ xmppout <- botdata.makeXMPPMessage(to, pec.Msg, nil)
+ }
}
+ default:
+ break
}
case je := <-jabber_events:
simple_jid := removeJIDResource(je.JID)
jid_data, jid_in_map := botdata.realraum_jids_[simple_jid]
if jid_in_map {
- jid_data.Online = je.Online
- if je.StatusNow && last_presence_event != nil {
- xmppout <- botdata.makeXMPPMessage(je.JID, composeMessage(last_presence_event, true), nil)
+ if last_status_msg != nil && (je.StatusNow || (! jid_data.Online && je.Online && jid_data.Wants == R3OnlineOnlyWithRecapInfo) ) {
+ xmppout <- botdata.makeXMPPMessage(je.JID, last_status_msg, nil)
}
+ jid_data.Online = je.Online
if je.Wants > R3NoChange {
jid_data.Wants = je.Wants
}
}
const help_text_ string = "\n*auth*<password>* ...Enables you to use more commands.\n*time* ...Returns bot time."
-const help_text_auth string = "You are authorized to use the following commands:\n*on* ...You will be notified of r3 status changes.\n*off* ...You will no longer recieve notifications.\n*on_while_offline* ...You will be notified of r3 status changes even if you are offline.\n*status* ...Query current status.\n*time* ...Returns bot time.\n*bye* ...Logout."
+const help_text_auth string = "You are authorized to use the following commands:\n*off* ...You will no longer receive notifications.\n*on* ...You will be notified of r3 status changes while you are online.\n*on_with_recap* ...Like *on* but additionally you will receive the current status when you come online.\n*on_while_offline* ...You will receive all r3 status changes, wether you are online or offline.\n*status* ...Use it to query the current status.\n*time* ...Returns bot time.\n*bye* ...Logout."
//~ var re_msg_auth_ *regexp.Regexp = regexp.MustCompile("auth\s+(\S+)")
if botdata.isAuthenticated(inmsg.GetHeader().From) {
switch bodytext {
case "on", "*on*":
- jabber_events <- JabberEvent{inmsg.GetHeader().From, true, R3NoOfflineInfo, false}
- xmppout <- botdata.makeXMPPMessage(inmsg.GetHeader().From, "Receive r3 information while online" , "Your New Status")
+ jabber_events <- JabberEvent{inmsg.GetHeader().From, true, R3OnlineOnlyInfo, false}
+ xmppout <- botdata.makeXMPPMessage(inmsg.GetHeader().From, "Receive r3 status updates while online." , "Your New Status")
case "off", "*off*":
- jabber_events <- JabberEvent{inmsg.GetHeader().From, true, R3NoInfo, false}
- xmppout <- botdata.makeXMPPMessage(inmsg.GetHeader().From, "Do not receive r3 information" , "Your New Status")
+ jabber_events <- JabberEvent{inmsg.GetHeader().From, true, R3NeverInfo, false}
+ xmppout <- botdata.makeXMPPMessage(inmsg.GetHeader().From, "Do not receive anything." , "Your New Status")
+ case "on_with_recap", "*on_with_recap*":
+ jabber_events <- JabberEvent{inmsg.GetHeader().From, true, R3OnlineOnlyWithRecapInfo, false}
+ xmppout <- botdata.makeXMPPMessage(inmsg.GetHeader().From, "Receive r3 status updates while and current status on coming, online." , "Your New Status")
case "on_while_offline", "*on_while_offline*":
- jabber_events <- JabberEvent{inmsg.GetHeader().From, true, R3AllInfo, false}
- xmppout <- botdata.makeXMPPMessage(inmsg.GetHeader().From, "Receive r3 information even while offline" , "Your New Status")
+ jabber_events <- JabberEvent{inmsg.GetHeader().From, true, R3AlwaysInfo, false}
+ xmppout <- botdata.makeXMPPMessage(inmsg.GetHeader().From, "Receive all r3 status updates, even if you are offline." , "Your New Status")
case "debug":
jabber_events <- JabberEvent{inmsg.GetHeader().From, true, R3DebugInfo, false}
xmppout <- botdata.makeXMPPMessage(inmsg.GetHeader().From, "Debug mode enabled" , "Your New Status")
case botdata.auth_cmd_, botdata.auth_cmd2_:
botdata.jid_lastauthtime_[inmsg.GetHeader().From] = time.Now().Unix()
xmppout <- botdata.makeXMPPMessage(inmsg.GetHeader().From, help_text_auth, nil)
- case "status", "*status*", "off", "*off*", "on", "*on*", "on_while_offline", "*on_while_offline*":
+ case "status", "*status*", "off", "*off*", "on", "*on*", "on_while_offline", "*on_while_offline*", "on_with_recap", "*on_with_recap*":
xmppout <- botdata.makeXMPPMessage(inmsg.GetHeader().From, "Sorry, you need to be authorized to do that." , nil)
case "time", "*time*":
xmppout <- botdata.makeXMPPMessage(inmsg.GetHeader().From, time.Now().String() , nil)
}
func (botdata *XmppBot) handleIncomingXMPPStanzas(xmppin <- chan xmpp.Stanza, xmppout chan<- xmpp.Stanza, jabber_events chan JabberEvent) {
+
+ defer func() {
+ if x := recover(); x != nil {
+ log.Printf("handleIncomingXMPPStanzas: run time panic: %v", x)
+ close(jabber_events)
+ }
+ }()
+
var incoming_stanza interface{}
for incoming_stanza = range xmppin {
switch stanza := incoming_stanza.(type) {
}
switch stanza.GetHeader().Type {
case "subscribe":
- xmppout <- botdata.makeXMPPPresence(stanza.GetHeader().From, "subscribed")
+ xmppout <- botdata.makeXMPPPresence(stanza.GetHeader().From, "subscribed", "", "")
jabber_events <- JabberEvent{stanza.GetHeader().From, true, R3NoChange, false}
- xmppout <- botdata.makeXMPPPresence(stanza.GetHeader().From, "subscribe")
+ xmppout <- botdata.makeXMPPPresence(stanza.GetHeader().From, "subscribe", "", "")
case "unsubscribe", "unsubscribed":
- jabber_events <- JabberEvent{stanza.GetHeader().From, false, R3NoInfo, false}
+ jabber_events <- JabberEvent{stanza.GetHeader().From, false, R3NeverInfo, false}
botdata.jid_lastauthtime_[stanza.GetHeader().From] = 0 //logout
- xmppout <- botdata.makeXMPPPresence(stanza.GetHeader().From, "unsubscribe")
+ xmppout <- botdata.makeXMPPPresence(stanza.GetHeader().From, "unsubscribe", "","")
case "unavailable":
jabber_events <- JabberEvent{stanza.GetHeader().From, false, R3NoChange, false}
botdata.jid_lastauthtime_[stanza.GetHeader().From] = 0 //logout
roster := xmpp.Roster(botdata.xmppclient_)
for _, entry := range roster {
if entry.Subscription == "from" {
- botdata.xmppclient_.Out <- botdata.makeXMPPPresence(entry.Jid, "subscribe")
+ botdata.xmppclient_.Out <- botdata.makeXMPPPresence(entry.Jid, "subscribe", "","")
}
if entry.Subscription == "none" {
delete(botdata.realraum_jids_, entry.Jid)