Commit 001e3bb4 authored by Philipp Hörist's avatar Philipp Hörist
Browse files

Client: Add ClientState.AVAILABLE

When we are connected to the server we need to set some things up
before we send our initial available presence. The new state makes
it possible for other code to difference between when we are connected
and when we are available.

For example other code should not send a presence before we requested
the roster.

Fixes #9983
parent c3d5945a
......@@ -612,7 +612,7 @@ def _screensaver_active(self, _application, _param):
if not active:
for account in app.connections:
if app.account_is_connected(account) and \
if app.account_is_available(account) and \
app.sleeper_state[account] == 'autoaway-forced':
# We came back online after screensaver autoaway
roster.send_status(account, 'online',
......@@ -628,7 +628,7 @@ def _screensaver_active(self, _application, _param):
not app.sleeper_state[account]):
continue
if app.sleeper_state[account] == 'online':
if not app.account_is_connected(account):
if not app.account_is_available(account):
continue
# we save our online status
app.status_before_autoaway[account] = \
......
......@@ -907,7 +907,7 @@ def _on_message_textview_key_press_event(self, widget, event):
is_ctrl_enter = bool(event_state & Gdk.ModifierType.CONTROL_MASK)
send_message = is_ctrl_enter == app.config.get('send_on_ctrl_enter')
if send_message and not app.account_is_connected(self.account):
if send_message and not app.account_is_available(self.account):
# we are not connected
app.interface.raise_dialog('not-connected-while-sending')
elif send_message:
......
......@@ -453,8 +453,13 @@ def account_supports_private_storage(account):
def account_is_connected(account):
if account not in connections:
return False
# 0 is offline, 1 is connecting
return connections[account].state.is_connected
return (connections[account].state.is_connected or
connections[account].state.is_available)
def account_is_available(account):
if account not in connections:
return False
return connections[account].state.is_available
def account_is_disconnected(account):
return not account_is_connected(account)
......
......@@ -185,6 +185,10 @@ def _on_resume_failed(self, _client, _signal_name):
def _on_resume_successful(self, _client, _signal_name):
self._set_state(ClientState.CONNECTED)
self._set_client_available()
def _set_client_available(self):
self._set_state(ClientState.AVAILABLE)
app.nec.push_incoming_event(NetworkEvent('account-connected',
account=self._account))
......@@ -282,8 +286,6 @@ def _on_connection_failed(self, _client, _signal_name):
def _on_connected(self, client, _signal_name):
self._set_state(ClientState.CONNECTED)
app.nec.push_incoming_event(NetworkEvent('account-connected',
account=self._account))
self.get_module('Discovery').discover_server_info()
self.get_module('Discovery').discover_account_info()
self.get_module('Discovery').discover_server_items()
......@@ -404,8 +406,8 @@ def _send_first_presence(self):
status=self._status_message)
self.priority = priority
app.nec.push_incoming_event(
OurShowEvent(None, conn=self, show=self._status))
self._set_client_available()
if not self.avatar_conversion:
# ask our VCard
......@@ -542,5 +544,7 @@ def cleanup(self):
pass
def quit(self, kill_core):
if kill_core and app.account_is_connected(self.name):
if kill_core and self._state in (ClientState.CONNECTING,
ClientState.CONNECTED,
ClientState.AVAILABLE):
self.disconnect(gracefully=True, reconnect=False)
......@@ -223,6 +223,7 @@ class ClientState(IntEnum):
RECONNECT_SCHEDULED = 2
CONNECTING = 3
CONNECTED = 4
AVAILABLE = 5
@property
def is_disconnecting(self):
......@@ -244,6 +245,11 @@ def is_connecting(self):
def is_connected(self):
return self == ClientState.CONNECTED
@property
def is_available(self):
return self == ClientState.AVAILABLE
MUC_CREATION_EXAMPLES = [
(Q_('?Group chat name:Team'),
......
......@@ -83,7 +83,7 @@ def start(self):
def _send_location(self):
accounts = app.connections.keys()
for acct in accounts:
if not app.account_is_connected(acct):
if not app.account_is_available(acct):
continue
if not app.config.get_per('accounts', acct, 'publish_location'):
continue
......
......@@ -199,7 +199,7 @@ def _pubsub_support(self) -> bool:
self._con.get_module('PubSub').publish_options)
def request_bookmarks(self) -> None:
if not app.account_is_connected(self._account):
if not app.account_is_available(self._account):
return
self._request_in_progress = True
......@@ -241,7 +241,7 @@ def store_difference(self, bookmarks: List) -> None:
self.store_bookmarks()
def store_bookmarks(self, bookmarks: list = None) -> None:
if not app.account_is_connected(self._account):
if not app.account_is_available(self._account):
return
type_ = BookmarkStoreType.PRIVATE
......@@ -260,7 +260,7 @@ def store_bookmarks(self, bookmarks: list = None) -> None:
NetworkEvent('bookmarks-received', account=self._account))
def store_bookmark(self, bookmark: BookmarkData) -> None:
if not app.account_is_connected(self._account):
if not app.account_is_available(self._account):
return
if not self.using_bookmark_2:
......
......@@ -133,7 +133,7 @@ def send_file_approval(self, file_props):
Send iq, confirming that we want to download the file
"""
# user response to ConfirmationDialog may come after we've disconneted
if not app.account_is_connected(self._account):
if not app.account_is_available(self._account):
return
# file transfer initiated by a jingle session
......@@ -176,7 +176,7 @@ def send_file_rejection(self, file_props):
invalid stream or 'profile' for invalid profile
"""
# user response to ConfirmationDialog may come after we've disconnected
if not app.account_is_connected(self._account):
if not app.account_is_available(self._account):
return
for session in self._con.get_module('Jingle').get_jingle_sessions(
......@@ -187,7 +187,7 @@ def send_success_connect_reply(self, streamhost):
"""
Send reply to the initiator of FT that we made a connection
"""
if not app.account_is_connected(self._account):
if not app.account_is_available(self._account):
return
if streamhost is None:
return
......@@ -251,7 +251,7 @@ def _send_socks5_info(self, file_props):
"""
Send iq for the present streamhosts and proxies
"""
if not app.account_is_connected(self._account):
if not app.account_is_available(self._account):
return
receiver = file_props.receiver
sender = file_props.sender
......@@ -498,7 +498,7 @@ def _connect_error(self, sid, error, error_type, msg=None):
Called when there is an error establishing BS connection, or when
connection is rejected
"""
if not app.account_is_connected(self._account):
if not app.account_is_available(self._account):
return
file_props = FilesProp.getFileProp(self._account, sid)
if file_props is None:
......@@ -528,7 +528,7 @@ def _proxy_auth_ok(self, proxy):
"""
Called after authentication to proxy server
"""
if not app.account_is_connected(self._account):
if not app.account_is_available(self._account):
return
file_props = FilesProp.getFileProp(self._account, proxy['sid'])
iq = nbxmpp.Iq(to=proxy['initiator'], typ='set')
......
......@@ -162,6 +162,9 @@ def update_caps(self):
COMMON_FEATURES + optional_features,
'https://gajim.org')
if not app.account_is_available(self._account):
return
app.connections[self._account].change_status(
app.connections[self._account].status,
app.connections[self._account].status_message)
......
......@@ -194,7 +194,7 @@ def _answer_disco_info(self, _con, stanza, _properties):
raise nbxmpp.NodeProcessed
def disco_muc(self, jid, callback=None):
if not app.account_is_connected(self._account):
if not app.account_is_available(self._account):
return
self._log.info('Request MUC info for %s', jid)
......
......@@ -38,7 +38,7 @@ def __init__(self, con):
]
def request_entity_time(self, jid, resource):
if not app.account_is_connected(self._account):
if not app.account_is_available(self._account):
return
if resource:
......
......@@ -26,7 +26,7 @@ def __init__(self, con):
BaseModule.__init__(self, con)
def unsubscribe(self, agent):
if not app.account_is_connected(self._account):
if not app.account_is_available(self._account):
return
iq = nbxmpp.Iq('set', nbxmpp.NS_REGISTER, to=agent)
iq.setQuery().setTag('remove')
......
......@@ -77,7 +77,7 @@ def _parse_metacontacts(stanza):
return meta_list
def store_metacontacts(self, tags_list):
if not app.account_is_connected(self._account):
if not app.account_is_available(self._account):
return
iq = nbxmpp.Iq('set', nbxmpp.NS_PRIVATE)
meta = iq.getQuery().addChild('storage',
......
......@@ -137,7 +137,7 @@ def pass_disco(self, info):
raise nbxmpp.NodeProcessed
def join(self, muc_data):
if not app.account_is_connected(self._account):
if not app.account_is_available(self._account):
return
self._manager.add(muc_data)
......@@ -151,7 +151,7 @@ def join(self, muc_data):
self._join(muc_data)
def create(self, muc_data):
if not app.account_is_connected(self._account):
if not app.account_is_available(self._account):
return
self._manager.add(muc_data)
......
......@@ -47,7 +47,7 @@ def _get_ping_iq(to: str) -> nbxmpp.Iq:
return iq
def send_ping(self, contact: ContactsT) -> None:
if not app.account_is_connected(self._account):
if not app.account_is_available(self._account):
return
to = contact.get_full_jid()
......
......@@ -297,13 +297,13 @@ def _unsubscribed_received(self, _con, _stanza, properties):
raise nbxmpp.NodeProcessed
def subscribed(self, jid):
if not app.account_is_connected(self._account):
if not app.account_is_available(self._account):
return
self._log.info('Subscribed: %s', jid)
self.send_presence(jid, 'subscribed')
def unsubscribed(self, jid):
if not app.account_is_connected(self._account):
if not app.account_is_available(self._account):
return
self._log.info('Unsubscribed: %s', jid)
......@@ -311,7 +311,7 @@ def unsubscribed(self, jid):
self.send_presence(jid, 'unsubscribed')
def unsubscribe(self, jid, remove_auth=True):
if not app.account_is_connected(self._account):
if not app.account_is_available(self._account):
return
if remove_auth:
self._con.get_module('Roster').del_item(jid)
......@@ -326,7 +326,7 @@ def unsubscribe(self, jid, remove_auth=True):
self._con.get_module('Roster').set_item(jid)
def subscribe(self, jid, msg=None, name='', groups=None, auto_auth=False):
if not app.account_is_connected(self._account):
if not app.account_is_available(self._account):
return
if groups is None:
groups = []
......
......@@ -43,7 +43,7 @@ def pass_disco(self, info):
self.publish_options = True
def send_pb_subscription_query(self, jid, cb, **kwargs):
if not app.account_is_connected(self._account):
if not app.account_is_available(self._account):
return
query = nbxmpp.Iq('get', to=jid)
......@@ -53,7 +53,7 @@ def send_pb_subscription_query(self, jid, cb, **kwargs):
self._con.connection.SendAndCallForResponse(query, cb, kwargs)
def send_pb_subscribe(self, jid, node, cb, **kwargs):
if not app.account_is_connected(self._account):
if not app.account_is_available(self._account):
return
our_jid = app.get_jid_from_account(self._account)
......@@ -64,7 +64,7 @@ def send_pb_subscribe(self, jid, node, cb, **kwargs):
self._con.connection.SendAndCallForResponse(query, cb, kwargs)
def send_pb_unsubscribe(self, jid, node, cb, **kwargs):
if not app.account_is_connected(self._account):
if not app.account_is_available(self._account):
return
our_jid = app.get_jid_from_account(self._account)
......@@ -76,7 +76,7 @@ def send_pb_unsubscribe(self, jid, node, cb, **kwargs):
def send_pb_publish(self, jid, node, item,
id_=None, options=None, cb=None, **kwargs):
if not app.account_is_connected(self._account):
if not app.account_is_available(self._account):
return
if cb is None:
......@@ -111,7 +111,7 @@ def send_pb_retrieve(self, jid, node, item_id=None, cb=None, **kwargs):
"""
Get items from a node
"""
if not app.account_is_connected(self._account):
if not app.account_is_available(self._account):
return
if cb is None:
......@@ -125,7 +125,7 @@ def send_pb_retract(self, jid, node, id_, cb=None, **kwargs):
"""
Delete item from a node
"""
if not app.account_is_connected(self._account):
if not app.account_is_available(self._account):
return
if cb is None:
......@@ -142,7 +142,7 @@ def send_pb_purge(self, jid, node, cb=None, **kwargs):
"""
Purge node: Remove all items
"""
if not app.account_is_connected(self._account):
if not app.account_is_available(self._account):
return
if cb is None:
......@@ -158,7 +158,7 @@ def send_pb_delete(self, jid, node, on_ok=None, on_fail=None):
"""
Delete node
"""
if not app.account_is_connected(self._account):
if not app.account_is_available(self._account):
return
query = nbxmpp.Iq('set', to=jid)
pubsub = query.addChild('pubsub', namespace=nbxmpp.NS_PUBSUB_OWNER)
......@@ -179,7 +179,7 @@ def send_pb_create(self, jid, node, cb,
"""
Create a new node
"""
if not app.account_is_connected(self._account):
if not app.account_is_available(self._account):
return
query = nbxmpp.Iq('set', to=jid)
pubsub = query.addChild('pubsub', namespace=nbxmpp.NS_PUBSUB)
......@@ -192,7 +192,7 @@ def send_pb_create(self, jid, node, cb,
self._con.connection.SendAndCallForResponse(query, cb)
def send_pb_configure(self, jid, node, form, cb=None, **kwargs):
if not app.account_is_connected(self._account):
if not app.account_is_available(self._account):
return
if cb is None:
......@@ -207,7 +207,7 @@ def send_pb_configure(self, jid, node, form, cb=None, **kwargs):
self._con.connection.SendAndCallForResponse(query, cb, kwargs)
def request_pb_configuration(self, jid, node):
if not app.account_is_connected(self._account):
if not app.account_is_available(self._account):
return
query = nbxmpp.Iq('get', to=jid)
......
......@@ -38,7 +38,7 @@ def __init__(self, con):
self.agent_registrations = {}
def register_agent(self, agent, form, is_form, success_cb, error_cb):
if not app.account_is_connected(self._account):
if not app.account_is_available(self._account):
return
weak_success_cb = weakref.WeakMethod(success_cb)
......@@ -76,7 +76,7 @@ def _register_agent_response(self, _nbxmpp_client, stanza, agent,
success_cb()()
def get_register_form(self, jid, success_cb, error_cb):
if not app.account_is_connected(self._account):
if not app.account_is_available(self._account):
return
weak_success_cb = weakref.WeakMethod(success_cb)
......
......@@ -271,14 +271,14 @@ def get_name(self, jid):
return self._get_item_data(jid, 'name')
def update_contact(self, jid, name, groups):
if app.account_is_connected(self._account):
if app.account_is_available(self._account):
self.set_item(jid=jid, name=name, groups=groups)
def update_contacts(self, contacts):
"""
Update multiple roster items
"""
if app.account_is_connected(self._account):
if app.account_is_available(self._account):
self.set_item_multi(contacts)
def set_item(self, jid, name=None, groups=None):
......
......@@ -94,7 +94,7 @@ def received_item(self, _con, stanza, _properties):
raise nbxmpp.NodeProcessed
def send_contacts(self, contacts, fjid, type_='message'):
if not app.account_is_connected(self._account):
if not app.account_is_available(self._account):
return
if type_ == 'message':
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment