class DigsbyProfileImporter(object): def __init__(self, username, password): self.callback = None self.identity = hooks.first('digsby.identity.create', username, password) self.connection = DigsbyProtocol(username, password, profile=Null, user=None, server=("digsby.org", 5555), login_as='invisible', do_tls=False, sasl_md5=False, digsby_login=True) def import_profile(self, callback=None): if self.callback is not None: raise Exception("Import already in progress") self.callback = callback self.connection.add_observer(self.on_conn_state_changed, 'state', 'offline_reason') self.connection.Connect(invisible=True, on_fail=self._on_conn_error) import_profile = callbacks.callsback(import_profile, ('success', 'error', 'progress')) def _on_conn_error(self, *a): self.error() def on_conn_state_changed(self, source, attr, old, new): if source is not self.connection: return if attr == 'offline_reason' and new == self.connection.Reasons.BAD_PASSWORD: return self.error(self.connection.offline_reason) if attr != 'state': return self.progress() if old == self.connection.Statuses.AUTHORIZED or new != self.connection.Statuses.AUTHORIZED: return log.info("Importer connection status: %r -> %r", old, new) blob_names = blobs.name_to_ns.keys() self.waiting_for = set(blob_names) for blob_name in blob_names: log.info("Requesting blob: %r", blob_name) self.connection.get_blob_raw(blob_name, success=self._blob_fetch_success, error=self._blob_fetch_error) self.waiting_for.add('accounts') self.connection.get_accounts(success=self._accounts_fetch_success, error=self._accounts_fetch_error) def got_item(self, name, data): log.info("Got blob: %r, saving.", name) self.identity.set(name, data) self.waiting_for.discard(name) log.info("\tNow waiting for: %r", self.waiting_for) if not len(self.waiting_for): self.success() def _blob_fetch_success(self, stanza): ns = stanza.get_query_ns() blob = blobs.ns_to_obj[ns](stanza.get_query()) name = blobs.ns_to_name[ns] self.got_item(name, blob.data) def _blob_fetch_error(self, *_a): self.error() def _accounts_fetch_success(self, stanza): fetched_accounts = accounts.Accounts(stanza.get_query()) self.got_item('accounts', fetched_accounts) def _accounts_fetch_error(self, *_a): self.error() def disconnect(self): conn, self.connection = self.connection, None if conn is not None: conn.remove_observer(self.on_conn_state_changed, 'state') conn.Disconnect() def progress(self): callback = getattr(self, 'callback', None) if callback is not None: getattr(callback, 'progress', lambda x: None)(self) def error(self, *a): self._cleanup('error', *a) def success(self): self._cleanup('success') def _cleanup(self, status, *a): util.threaded(self.disconnect)() callback, self.callback = self.callback, None if callback is not None: getattr(callback, status, lambda: None)(*a)
class DigsbyProfileImporter(object): def __init__(self, username, password): self.callback = None self.identity = hooks.first("digsby.identity.create", username, password) self.connection = DigsbyProtocol( username, password, profile=Null, user=None, server=("digsby.org", 5555), login_as="invisible", do_tls=False, sasl_md5=False, digsby_login=True, ) def import_profile(self, callback=None): if self.callback is not None: raise Exception("Import already in progress") self.callback = callback self.connection.add_observer(self.on_conn_state_changed, "state", "offline_reason") self.connection.Connect(invisible=True, on_fail=self._on_conn_error) import_profile = callbacks.callsback(import_profile, ("success", "error", "progress")) def _on_conn_error(self, *a): self.error() def on_conn_state_changed(self, source, attr, old, new): if source is not self.connection: return if attr == "offline_reason" and new == self.connection.Reasons.BAD_PASSWORD: return self.error(self.connection.offline_reason) if attr != "state": return self.progress() if old == self.connection.Statuses.AUTHORIZED or new != self.connection.Statuses.AUTHORIZED: return log.info("Importer connection status: %r -> %r", old, new) blob_names = blobs.name_to_ns.keys() self.waiting_for = set(blob_names) for blob_name in blob_names: log.info("Requesting blob: %r", blob_name) self.connection.get_blob_raw(blob_name, success=self._blob_fetch_success, error=self._blob_fetch_error) self.waiting_for.add("accounts") self.connection.get_accounts(success=self._accounts_fetch_success, error=self._accounts_fetch_error) def got_item(self, name, data): log.info("Got blob: %r, saving.", name) self.identity.set(name, data) self.waiting_for.discard(name) log.info("\tNow waiting for: %r", self.waiting_for) if not len(self.waiting_for): self.success() def _blob_fetch_success(self, stanza): ns = stanza.get_query_ns() blob = blobs.ns_to_obj[ns](stanza.get_query()) name = blobs.ns_to_name[ns] self.got_item(name, blob.data) def _blob_fetch_error(self, *_a): self.error() def _accounts_fetch_success(self, stanza): fetched_accounts = accounts.Accounts(stanza.get_query()) self.got_item("accounts", fetched_accounts) def _accounts_fetch_error(self, *_a): self.error() def disconnect(self): conn, self.connection = self.connection, None if conn is not None: conn.remove_observer(self.on_conn_state_changed, "state") conn.Disconnect() def progress(self): callback = getattr(self, "callback", None) if callback is not None: getattr(callback, "progress", lambda x: None)(self) def error(self, *a): self._cleanup("error", *a) def success(self): self._cleanup("success") def _cleanup(self, status, *a): util.threaded(self.disconnect)() callback, self.callback = self.callback, None if callback is not None: getattr(callback, status, lambda: None)(*a)