def on_close(self): if getattr(self, "_closed", False): log.warning("FIXME: imwin_ctrl.on_close was called more than once!!!") return self._closed = True del self.capsbar.buddy_callback del self.capsbar import hooks hooks.notify("digsby.overlay_icon_updated", self) from plugin_manager import plugin_hub plugin_hub.act("digsby.im.conversation.close.async", self.convo) self.unlink_observers() if self.convo is not None: self.unwatch_conversation(self.convo) try: self.convo.explicit_exit() except Exception: print_exc()
def return_from_idle(self): if self.idle: # $$plugin load import plugin_manager.plugin_hub as plugin_hub if not plugin_hub.act('digsby.unidle.pre'): return plugin_hub.act('digsby.unidle.async') self.idle = False for acct in profile.account_manager.connected_accounts: try: acct.connection.set_idle(0) except Exception: log.error('Failed to return from idle on this account: %r', acct) print_exc() log.info('return from idle') from common import pref util.call_later(pref('profile.idle_return_delay', default=0, type=int), self.OnReturnFromIdle.call_and_clear) if self.last_status is not None: self.set_status(self.last_status) self.last_status = None
def _received_emails(self, emails, inboxCount = None): ''' Subclasses should call this method with any new emails received. @param emails: a sequence of Email objects ''' old, self.emails[:] = self.emails[:], list(emails) new = self._get_new() for email in new: import plugin_manager.plugin_hub as plugin_hub plugin_hub.act('digsby.mail.newmessage.async', self, email) self._see_new(new) self.sort_emails(new) new = self.filter_new(new, old) del old info('%s - %s: %d new emails', self.__class__.__name__, self.name, len(new)) if inboxCount is not None: self._setInboxCount(inboxCount) self.new = new if new: profile.when_active(self.fire_notification) self.error_count = 0 self.change_state(self.Statuses.ONLINE) self._dirty_error = True # Next error will be new
def on_close(self): if getattr(self, '_closed', False): log.warning( 'FIXME: imwin_ctrl.on_close was called more than once!!!') return self._closed = True del self.capsbar.buddy_callback del self.capsbar import hooks hooks.notify('digsby.overlay_icon_updated', self) from plugin_manager import plugin_hub plugin_hub.act('digsby.im.conversation.close.async', self.convo) self.unlink_observers() if self.convo is not None: self.unwatch_conversation(self.convo) try: self.convo.explicit_exit() except Exception: print_exc()
def buddy_says(self, buddy, message, **options): '@return: True if the message was allowed' if not isinstance(message, unicode): raise TypeError, 'buddy_says needs unicode got type %r: %r' % (type(message), message) try: timestamp = options.get('timestamp', None) if timestamp is None: timestamp = datetime.utcnow() content_type = options.pop('content_type', 'text/plain') from common.message import Message messageobj = Message(buddy = buddy, message = message, timestamp = timestamp, content_type = content_type) from plugin_manager import plugin_hub msgtype = options.get('type', None) # Allow plugins to make changes to the messageobj plugin_hub.act('digsby.im.msg.pre', messageobj, msgtype) if messageobj.message != '': # TODO: pass entire (potentially) changed messageobj to self._message return self._message(buddy, messageobj.message, content_type = messageobj.content_type, **options) except Exception, e: log.error("Failed to parse message %r",e) # do what it used to do return self._message(buddy, message, **options)
def _message(self, buddy, message, **options): '@return: True if the message was allowed' # Always use local time for online messages, in case user's clock is wrong. if not options.get('offline', True): options.pop('timestamp', None) if options.get('offline', False): self.autoresponded = True # Prevent autoresponse to offline messages # if timestamp is None substitute it with UTC now timestamp = options.pop('timestamp', None) if timestamp is None: timestamp = datetime.utcnow() from common.message import Message messageobj = Message(buddy=buddy, message=message, timestamp=timestamp, conversation=self, **options) from plugin_manager import plugin_hub plugin_hub.act('digsby.im.msg.async', self, messageobj, options.get('type', None)) from common import profile return profile.on_message(messageobj) is not profile.on_message.VETO
def set_idle(self, *a, **k): self.idle_timer.stop() # $$plugin load import plugin_manager.plugin_hub as plugin_hub if not plugin_hub.act('digsby.goidle.pre'): return plugin_hub.act('digsby.goidle.async') from common import pref if not pref('messaging.become_idle'): log.debug('idle is not enabled') return if self.status.invisible or self.status.offline: log.debug('currently invisible, not setting idle') return idle_msg = self.status.copy(status=StatusMessage.Idle.status) self.last_status = self.status self.setnotify('status', idle_msg) for acct in self.account_manager.connected_accounts: log.info('Setting idle on %r to %r', acct, self.idle_timer._interval) try: acct.connection.set_idle(self.idle_timer._interval) except Exception: log.error('Failed to set idle on this account: %r', acct) print_exc() log.info('setting idle = True') self.idle = True
def buddy_says(self, buddy, message, **options): '@return: True if the message was allowed' if not isinstance(message, unicode): raise TypeError, 'buddy_says needs unicode got type %r: %r' % ( type(message), message) try: timestamp = options.get('timestamp', None) if timestamp is None: timestamp = datetime.utcnow() content_type = options.pop('content_type', 'text/plain') from common.message import Message messageobj = Message(buddy=buddy, message=message, timestamp=timestamp, content_type=content_type) from plugin_manager import plugin_hub msgtype = options.get('type', None) # Allow plugins to make changes to the messageobj plugin_hub.act('digsby.im.msg.pre', messageobj, msgtype) if messageobj.message != '': # TODO: pass entire (potentially) changed messageobj to self._message return self._message(buddy, messageobj.message, content_type=messageobj.content_type, **options) except Exception, e: log.error("Failed to parse message %r", e) # do what it used to do return self._message(buddy, message, **options)
def update_account(self, account, force=False): self.account_manager.update_account(account, force=force) # $$plugin import plugin_manager.plugin_hub as plugin_hub plugin_hub.act('digsby.updateaccount.async', account)
def _message(self, buddy, message, **options): '@return: True if the message was allowed' # Always use local time for online messages, in case user's clock is wrong. if not options.get('offline', True): options.pop('timestamp', None) if options.get('offline', False): self.autoresponded = True # Prevent autoresponse to offline messages # if timestamp is None substitute it with UTC now timestamp = options.pop('timestamp', None) if timestamp is None: timestamp = datetime.utcnow() from common.message import Message messageobj = Message(buddy = buddy, message = message, timestamp = timestamp, conversation = self, **options) from plugin_manager import plugin_hub plugin_hub.act('digsby.im.msg.async', self, messageobj, options.get('type', None)) from common import profile return profile.on_message(messageobj) is not profile.on_message.VETO
def signoff(self, kicked=False): 'Return to the splash screen.' # $$plugin unload import plugin_manager.plugin_hub as plugin_hub plugin_hub.act('digsby.plugin.unload.async') if platformName == 'win': return wx.GetApp().Restart() # todo: confirm if there are (active) file transfers # hide all top level windows top = wx.GetTopLevelWindows for win in top(): win.Hide() del self.on_message[:] del self.OnReturnFromIdle[:] self.stop_timers() def dodisconnect(success = True): if not success: log.info('there was an error saving all blobs.') # disconnect all accounts with traceguard: self.disconnect() # destroy all top level windows f = getattr(wx.GetApp(), 'buddy_frame', None) if f: f.on_destroy() for win in top(): with traceguard: if not win.IsDestroyed(): win.Destroy() # clear input shortcuts from gui.input.inputmanager import input_manager input_manager.reset() import gc import observe gc.collect() numCleared = observe.clear_all() log.info('cleared %d observers dicts', numCleared) # show the splash, preventing autologin wx.GetApp().ShowSplash(autologin_override = False, kicked=kicked) log.info('saving all blobs before signoff...') self.save(success = dodisconnect, error = lambda: dodisconnect(False)) from gui import toast toast.cancel_all()
def _received_emails(self, emails, inboxCount=None): ''' Subclasses should call this method with any new emails received. @param emails: a sequence of Email objects ''' old, self.emails[:] = self.emails[:], list(emails) new = self._get_new() for email in new: import plugin_manager.plugin_hub as plugin_hub plugin_hub.act('digsby.mail.newmessage.async', self, email) self._see_new(new) self.sort_emails(new) new = self.filter_new(new, old) del old info('%s - %s: %d new emails', self.__class__.__name__, self.name, len(new)) if inboxCount is not None: self._setInboxCount(inboxCount) self.new = new if new: profile.when_active(self.fire_notification) self.error_count = 0 self.change_state(self.Statuses.ONLINE) self._dirty_error = True # Next error will be new
def _setup_plugins(self): for hook in Hook('digsby.profile.addons'): try: getattr(hook(self), 'setup', lambda *a, **k: None)() except Exception: traceback.print_exc() import plugin_manager.plugin_hub as plugin_hub plugin_hub.act('digsby.plugin.load.async')
def add_email_account(self, **info): protocol = info.get('protocol') name = info.get('name') self.account_manager.add(proto_init(protocol)(**info), 'em') # $$plugin import plugin_manager.plugin_hub as plugin_hub plugin_hub.act('digsby.email.addaccount.async', protocol, name)
def connection_status_monitor(self, src, attr, old, new): assert src is self if new == self.Statuses.OFFLINE: self._unregister_buddies() from plugin_manager import plugin_hub plugin_hub.act('digsby.protocol.statechange.async', self, attr, old, new) state_log.critical('%r: %r changed from <%r> to <%r>', self, attr, old, new)
def add_social_account(self, **info): protocol = info.pop('protocol') name = info.get('name') acct = proto_init(protocol)(**info) self.account_manager.add(acct, 'so') # $$plugin import plugin_manager.plugin_hub as plugin_hub plugin_hub.act('digsby.social.addaccount.async', protocol, name) return acct
def get_component(self, type, create = True): if type not in self.get_component_types(): return None if type not in self.accounts and create: component = self.construct_component(type) if component is not None: self.add_account(type, component) plugin_hub.act('digsby.%s.addaccount.async' % type, component.protocol, component.name) return self.accounts.get(type, None)
def release_accounts(self, autologin=False): ''' function to be called to apply all network account changes received from the network. ''' with self.acct_delay_lock: self.delay_accounts = False self.acct_calls.call_and_clear() import plugin_manager.plugin_hub as plugin_hub plugin_hub.act('digsby.accounts.released.async') if autologin and sys.opts.autologin_accounts: log.debug('doing autologin') self.autologin()
def watch_conversation(self, convo): from plugin_manager import plugin_hub plugin_hub.act("digsby.im.conversation.open.async", convo) convo.typing_status.add_observer(self.typing_status_changed) convo.add_observer(self._update_caps_and_title, "ischat") buddy = convo.buddy buddy.add_observer(self.buddy_status_changed, "status") buddy.add_observer(self.buddy_info_changed) if convo.ischat: convo.room_list.add_observer(self.chat_buddies_changed) convo.conversation_reconnected.add_unique(self.on_conversation_reconnected) convo.protocol.add_observer(self._on_convo_proto_state_change, "state")
def watch_conversation(self, convo): from plugin_manager import plugin_hub plugin_hub.act('digsby.im.conversation.open.async', convo) convo.typing_status.add_observer(self.typing_status_changed) convo.add_observer(self._update_caps_and_title, 'ischat') buddy = convo.buddy buddy.add_observer(self.buddy_status_changed, 'status') buddy.add_observer(self.buddy_info_changed) if convo.ischat: convo.room_list.add_observer(self.chat_buddies_changed) convo.conversation_reconnected.add_unique( self.on_conversation_reconnected) convo.protocol.add_observer(self._on_convo_proto_state_change, 'state')
def set_formatted_profile(self, protocol, fstr=None): if fstr is None: fstr = self.profile # $$plugin setprofile import plugin_manager.plugin_hub as plugin_hub if not plugin_hub.act('digsby.im.setprofile.pre', protocol, fstr): return plugin_hub.act('digsby.im.setprofile.async', protocol, fstr) add_promo_string = self.prefs.get('profile.promote', True) if fstr.bestFormat == "rtf": if add_promo_string: fstr = fstr + PROMOTE_STRING_RTF format = None else: #legacy profile support if add_promo_string: fstr = fstr.format_as("plaintext").encode('xml') + PROMOTE_STRING_HTML from gui.uberwidgets.formattedinput import get_default_format format = get_default_format('profile.formatting') netcall(lambda: protocol.set_profile(fstr, format))
def add_account(self, **attrdict): # $$plugin self.account_manager.add(Account(**attrdict), 'im') import plugin_manager.plugin_hub as plugin_hub plugin_hub.act('digsby.im.addaccount.async', attrdict['protocol'], attrdict['name'])
def set_status(self, status): ''' Takes a StatusMessage object and sets the status in all connected (and which will connect in the future) accounts. ''' if status == self.status: return log.warning('set_status got an identical status.') # $$plugin status change from plugin_manager import plugin_hub plugin_hub.act('digsby.im.mystatuschange.pre', status) if status == '': return plugin_hub.act('digsby.im.mystatuschange.async', status) for hook in Hook('digsby.im.statusmessages.set.pre'): # can't use query or notify (want the chained effect) status = hook(status) log.warning('set_status got %r', status) accts = [a for a in self.account_manager.connected_accounts if a is not self] def allaccts(func): for a in accts: with traceguard: func(a) Offline = StatusMessage.Offline # disconnecting if status == Offline: log.info('disconnecting all connected accounts') # store a list of the accounts which were connected prior # to disconnecting. self.were_connected = accts[:] self.were_connected_status = self.status allaccts(lambda a: a.disconnect()) #reconnecting elif self.status == Offline and hasattr(self, 'were_connected'): accts = self.were_connected del self.were_connected for acct in accts: with traceguard: if acct in self.account_manager.accounts: acct.connect(invisible=(status.for_account(acct).invisible)) else: log.warning('not reconnecting %s', acct) else: for acct in self.account_manager.connected_accounts[:]: with traceguard: prev_invis = self.status.for_account(acct).invisible this_invis = status.for_account(acct).invisible #going to/returning from invisible if (prev_invis or this_invis) and this_invis != prev_invis: acct.connection.set_invisible(this_invis) #just setting a status if not this_invis: acct.connection._set_status_object(status) self.setnotifyif('status', status.copy(editable=None, edit_toggle=None)) self.save_status() hooks.notify('digsby.im.statusmessages.set.post', self.status)
def remove_account(self, account): self.account_manager.remove(account) # $$plugin import plugin_manager.plugin_hub as plugin_hub plugin_hub.act('digsby.removeaccount.async', account)