webXMPP

Check-in [1def2b208b]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Fiddle with some edge cases of trying to do XMPP before the connection is considered up. TBD, reconnect if it goes down.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | master | trunk
Files: files | file ages | folders
SHA3-256: 1def2b208b7cd1db089523da23d87c315e79fd74dc5e34d647b16653ec98c8f4
User & Date: web 2020-05-18 23:04:51
Context
2020-05-26
23:44
Some more work getting reconnect flying. Finally just bit the bullet and stop/start'ed prosody while testing various scenarios. check-in: 81431ef981 user: web tags: master, trunk
2020-05-18
23:04
Fiddle with some edge cases of trying to do XMPP before the connection is considered up. TBD, reconnect if it goes down. check-in: 1def2b208b user: web tags: master, trunk
2020-05-06
01:11
Tighten up display of nicknames, integrate in destination selection check-in: bbb9ef0e3a user: web tags: master, trunk
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to acct_xmpp.py.

17
18
19
20
21
22
23

24
25
26
27
28
29
30

31
32
33
34
35
36
37
...
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153

154
155
156

157
158
159
160
161
162
163
164
165
166
167
168
169
170

171





















172
173
174
175
176
177
178
179
180
...
189
190
191
192
193
194
195
196
197
198
199
200
201

202
203

204


205
#  together for purposes of viewing.
#
# user - Back-reference to User instance we're serving
# acct/pw - Account name and its password
# conn - XMPP Client instance
# stopping - Bool flag to tell us to wrap up our service loop
# status - String, latest "show" status from peer

class Account(object):
    def __init__(self, user, acct, pw):
	self.user = user
	self.acct = acct
	self.pw = pw
	self.conn = None
	self.stopping = False


    # Send a message
    # (User exclusion is held.)
    def send(self, towhom, msg):
	self.conn.send( xmpp.Message(towhom, msg) )

    # Callback from XMPP stack when we get a message
................................................................................
	    newstat = "available"
	    if newstat != user.status.get(who, "NEW"):
		sys.stderr.write("no show, updating to assume %s %d\n" %
		    (newstat, user.rgen))
		user.rgen += 1
		user.status[who] = newstat

    # Update our presence
    def sendPresence(self, p):
	while not hasattr(self.conn, "send"):
	    # You have to be kidding me.
	    sys.stderr.write("XMPP connection, no send method yet\n")
	    time.sleep(0.5)
	self.conn.send(xmpp.Presence(status=p, show=p))

    # This runs under a dedicated thread

    def start(self):
	# Connect to the actual XMPP account
	acct = self.acct

	server = acct.split("@")[-1]
	jid = xmpp.JID(acct)
	self.conn = conn = xmpp.Client(server, debug=[])
	conn.connect()
	result = conn.auth(jid.getNode(),
	    self.pw, "webXMPP%d" % (os.getpid(),))
	if not result:
	    sys.stderr.write("Account %s XMPP start failed\n" % (self.acct,))
	    sys.exit(0)

	# Announce ourselves
	conn.sendInitPresence()
	conn.RegisterHandler('message', self.message)
	conn.RegisterHandler('presence', self.presence)























	# Fold in roster
	r = conn.getRoster()
	buds = set()
	nicks = self.user.approot.nicks
	for bud in r.getItems():
	    budstr = toascii(bud)
	    if '@' not in budstr:
		# Ignore aliases
		continue
................................................................................
	self.buddies = frozenset(buds)
	user = self.user
	for bud in buds:
	    user.roster[bud] = self
	del buds

	# And dispatch incoming messages
	while conn.Process(10):
	    # No single XMPP destination will chew us up
	    time.sleep(0.2)

	    # Cleanly terminate if so flagged
	    if self.stopping:

		for bud in self.buddies:
		    del user.roster[bud]

		conn.disconnect()


		sys.exit(0)







>







>







 







|
|
<
<
<
<
<

<
>
|
<

>











<


>

>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>

|







 







|





>


>
|
>
>

17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
...
140
141
142
143
144
145
146
147
148





149

150
151

152
153
154
155
156
157
158
159
160
161
162
163
164

165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
...
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
#  together for purposes of viewing.
#
# user - Back-reference to User instance we're serving
# acct/pw - Account name and its password
# conn - XMPP Client instance
# stopping - Bool flag to tell us to wrap up our service loop
# status - String, latest "show" status from peer
# saw_roster - Flag that we've received our first roster
class Account(object):
    def __init__(self, user, acct, pw):
	self.user = user
	self.acct = acct
	self.pw = pw
	self.conn = None
	self.stopping = False
	self.saw_roster = False

    # Send a message
    # (User exclusion is held.)
    def send(self, towhom, msg):
	self.conn.send( xmpp.Message(towhom, msg) )

    # Callback from XMPP stack when we get a message
................................................................................
	    newstat = "available"
	    if newstat != user.status.get(who, "NEW"):
		sys.stderr.write("no show, updating to assume %s %d\n" %
		    (newstat, user.rgen))
		user.rgen += 1
		user.status[who] = newstat

	# Ok, we've now seen at least a part of our roster
	self.saw_roster = True







    # Establish the XMPP connection
    def reconnect(self):

	acct = self.acct
	self.saw_roster = False
	server = acct.split("@")[-1]
	jid = xmpp.JID(acct)
	self.conn = conn = xmpp.Client(server, debug=[])
	conn.connect()
	result = conn.auth(jid.getNode(),
	    self.pw, "webXMPP%d" % (os.getpid(),))
	if not result:
	    sys.stderr.write("Account %s XMPP start failed\n" % (self.acct,))
	    sys.exit(0)

	# Announce ourselves

	conn.RegisterHandler('message', self.message)
	conn.RegisterHandler('presence', self.presence)
	conn.sendInitPresence()

    # Update our presence
    def sendPresence(self, p):
	sys.stderr.write("Presence %s = %s\n" % (self.user, p))

	# Don't send presence until you see a roster (and thus,
	#  the presence of your buddies)
	if not self.saw_roster:
	    sys.stderr.write("presence before roster, hiding\n")
	    return

	while not hasattr(self.conn, "send"):
	    # You have to be kidding me.
	    sys.stderr.write("XMPP connection, no send method yet\n")
	    time.sleep(0.5)
	self.conn.send(xmpp.Presence(status=p, show=p))

    # This runs under a dedicated thread
    def start(self):
	# Connect to the actual XMPP account
	self.reconnect()

	# Fold in roster
	r = self.conn.getRoster()
	buds = set()
	nicks = self.user.approot.nicks
	for bud in r.getItems():
	    budstr = toascii(bud)
	    if '@' not in budstr:
		# Ignore aliases
		continue
................................................................................
	self.buddies = frozenset(buds)
	user = self.user
	for bud in buds:
	    user.roster[bud] = self
	del buds

	# And dispatch incoming messages
	while self.conn.Process(10):
	    # No single XMPP destination will chew us up
	    time.sleep(0.2)

	    # Cleanly terminate if so flagged
	    if self.stopping:
		sys.stderr.write("Stopping.\n")
		for bud in self.buddies:
		    del user.roster[bud]
		try:
		    conn.disconnect()
		except:
		    pass
		sys.exit(0)