home *** CD-ROM | disk | FTP | other *** search
/ Maximum CD 2011 October / maximum-cd-2011-10.iso / DiscContents / digsby_setup.exe / lib / common / Conversation.pyo (.txt) < prev    next >
Encoding:
Python Compiled Bytecode  |  2011-06-22  |  15.1 KB  |  439 lines

  1. # Source Generated with Decompyle++
  2. # File: in.pyo (Python 2.6)
  3.  
  4. from __future__ import with_statement
  5. from logging import getLogger
  6. from actions import ActionMeta
  7. from Buddy import get_bname
  8. from common import pref, profile, netcall, urlhandler
  9. from datetime import datetime
  10. from util.observe import Observable, ObservableList, observable_dict
  11. from util import traceguard
  12. log = getLogger('common.conversation')
  13. AUTORESP = _('[Auto-Response] ')
  14.  
  15. class Conversation(Observable):
  16.     __metaclass__ = ActionMeta
  17.     AUTORESP = AUTORESP
  18.     
  19.     def __init__(self, protocol):
  20.         Observable.__init__(self)
  21.         self.room_list = ObservableList()
  22.         self.protocol = protocol
  23.         self.autoresponded = False
  24.         self.typing_status = observable_dict()
  25.         self.just_had_error = False
  26.         self.pending_contacts_callbacks = set()
  27.         self.start_time_utc = datetime.utcnow()
  28.         self._bind_reconnect()
  29.         self.protocol.add_observer(self._Conversation__on_proto_state, 'state')
  30.         self.videochat_urlhandler = None
  31.  
  32.     
  33.     def _bind_reconnect(self):
  34.         if self.protocol is not None:
  35.             self.protocol.when_reconnect(self._Conversation__on_account_reconnect)
  36.         
  37.  
  38.     
  39.     def __on_proto_state(self, src, attr, old, new):
  40.         if new == src.Statuses.OFFLINE and self.ischat:
  41.             import wx
  42.             wx.CallLater((500,), (lambda : self.system_message(_('Disconnected'))))
  43.             self.protocol.remove_observer(self._Conversation__on_proto_state, 'state')
  44.         
  45.  
  46.     
  47.     def conversation_reconnected(self):
  48.         
  49.         try:
  50.             d = self._conversation_reconnected
  51.         except AttributeError:
  52.             Delegate = Delegate
  53.             import util.primitives.funcs
  54.             d = self._conversation_reconnected = Delegate()
  55.  
  56.         return d
  57.  
  58.     conversation_reconnected = property(conversation_reconnected)
  59.     
  60.     def __on_account_reconnect(self, new_connection):
  61.         
  62.         def foo():
  63.             log.warning('on_account_reconnect - connection: %r', new_connection)
  64.             log.warning('  ischat: %r', self.ischat)
  65.             if self.ischat:
  66.                 
  67.                 def success(convo):
  68.                     log.warning('rejoin_chat success: %r', convo)
  69.                     self.conversation_reconnected(convo)
  70.  
  71.                 log.warning('rejoin_chat')
  72.                 new_connection.rejoin_chat(self, success = success)
  73.             
  74.  
  75.         
  76.         def later():
  77.             netcall(foo)
  78.  
  79.         import wx
  80.         wx.CallLater(1000, later)
  81.  
  82.     
  83.     def add_pending_contacts(self, contacts):
  84.         for cb in self.pending_contacts_callbacks:
  85.             cb(contacts)
  86.         
  87.  
  88.     
  89.     def maybe_send_typing_status(self, status):
  90.         if pref('privacy.send_typing_notifications', False):
  91.             self.send_typing_status(status)
  92.         
  93.  
  94.     
  95.     def icon(self):
  96.         if self.ischat:
  97.             skin = skin
  98.             import gui
  99.             return skin.get('serviceicons.digsby')
  100.         return self.buddy.icon
  101.  
  102.     icon = property(icon)
  103.     
  104.     def send_plaintext_message(self, message):
  105.         return self._send_message(default_formatted_text(message))
  106.  
  107.     
  108.     def send_message(self, message, *args, **kwargs):
  109.         import hooks
  110.         message = hooks.reduce('digsby.im.msg.send', message)
  111.         echonow = pref('messaging.echo_immediately', type = bool, default = True)
  112.         
  113.         def error(e = (None, None)):
  114.             log.info('Error sending message: %r', message.format_as('plaintext'))
  115.             log.info('Message error callback received %r: %r', type(e), e)
  116.             if self.just_had_error:
  117.                 return None
  118.             emsg = getattr(e, 'error_message', '')
  119.             if emsg:
  120.                 self.system_message(emsg, content_type = 'text/plain')
  121.             else:
  122.                 self.system_message(_('Some of the messages you sent may not have been received.'), content_type = 'text/plain')
  123.             self.just_had_error = True
  124.  
  125.         
  126.         def message_sent():
  127.             self.just_had_error = False
  128.  
  129.         
  130.         def echo_message(msg = (None, (None,), None)):
  131.             if not msg:
  132.                 pass
  133.             echomsg = message
  134.             if kwargs.get('auto', False):
  135.                 if 'has_autotext' not in kwargs:
  136.                     kwargs.update(has_autotext = True)
  137.                 
  138.             
  139.             self.sent_message(echomsg, **kwargs)
  140.  
  141.         if echonow:
  142.             
  143.             def success(msg = (None,)):
  144.                 message_sent()
  145.  
  146.             echo_message()
  147.         else:
  148.             
  149.             def success(msg = (None, None)):
  150.                 message_sent()
  151.                 echo_message(msg)
  152.  
  153.         conn = profile.connection
  154.         if conn is not None:
  155.             conn.send_message_intercept(self.buddy, message.format_as('plaintext'))
  156.         
  157.         (None, None, None, None, None, netcall)((lambda : self._send_message(message, success = success, error = error, *args, **kwargs)))
  158.         if not self.ischat:
  159.             b = self.buddy
  160.             if b is not None and b is not self.protocol.self_buddy:
  161.                 profile.blist.add_tofrom('im', b, self.protocol)
  162.             
  163.         
  164.  
  165.     
  166.     def system_message(self, message, **opts):
  167.         log.debug('System message: message=%r, opts=%r', message, opts)
  168.         opts['buddy'] = None
  169.         opts['type'] = 'status'
  170.         return self._message(message = message, **opts)
  171.  
  172.     
  173.     def important_system_message(self, message, **opts):
  174.         opts['system_message_raises'] = True
  175.         return self.system_message(message, **opts)
  176.  
  177.     
  178.     def buddy_says(self, buddy, message, **options):
  179.         if not isinstance(message, unicode):
  180.             raise TypeError, 'buddy_says needs unicode got type %r: %r' % (type(message), message)
  181.         isinstance(message, unicode)
  182.         
  183.         try:
  184.             timestamp = options.get('timestamp', None)
  185.             if timestamp is None:
  186.                 timestamp = datetime.utcnow()
  187.             
  188.             content_type = options.pop('content_type', 'text/plain')
  189.             Message = Message
  190.             import common.message
  191.             messageobj = Message(buddy = buddy, message = message, timestamp = timestamp, content_type = content_type)
  192.             plugin_hub = plugin_hub
  193.             import plugin_manager
  194.             msgtype = options.get('type', None)
  195.             plugin_hub.act('digsby.im.msg.pre', messageobj, msgtype)
  196.             if messageobj.message != '':
  197.                 return self._message(buddy, messageobj.message, content_type = messageobj.content_type, **options)
  198.         except Exception:
  199.             e = None
  200.             log.error('Failed to parse message %r', e)
  201.             return self._message(buddy, message, **options)
  202.  
  203.  
  204.     
  205.     def _message(self, buddy, message, **options):
  206.         if not options.get('offline', True):
  207.             options.pop('timestamp', None)
  208.         
  209.         if options.get('offline', False):
  210.             self.autoresponded = True
  211.         
  212.         timestamp = options.pop('timestamp', None)
  213.         if timestamp is None:
  214.             timestamp = datetime.utcnow()
  215.         
  216.         Message = Message
  217.         import common.message
  218.         messageobj = Message(buddy = buddy, message = message, timestamp = timestamp, conversation = self, **options)
  219.         plugin_hub = plugin_hub
  220.         import plugin_manager
  221.         plugin_hub.act('digsby.im.msg.async', self, messageobj, options.get('type', None))
  222.         profile = profile
  223.         import common
  224.         return profile.on_message(messageobj) is not profile.on_message.VETO
  225.  
  226.     
  227.     def received_message(self, buddy, message, **options):
  228.         if not isinstance(message, unicode):
  229.             raise TypeError('message argument must be unicode')
  230.         isinstance(message, unicode)
  231.         return self.buddy_says(buddy, message, type = 'incoming', **options)
  232.  
  233.     
  234.     def sent_message(self, message, **options):
  235.         buddy = self.self_buddy
  236.         traceguard.__enter__()
  237.         
  238.         try:
  239.             message = message.format_as('xhtml')
  240.             options['content_type'] = 'text/xhtml'
  241.         finally:
  242.             pass
  243.  
  244.         self.autoresponded = True
  245.         return self.buddy_says(buddy, message, type = 'outgoing', **options)
  246.  
  247.     
  248.     def incoming_message(self, autoresp = True):
  249.         status = profile.status.for_account(self.protocol)
  250.         StatusMessage = StatusMessage
  251.         import common
  252.         if all((autoresp, status.away, not (status.invisible), status != StatusMessage.Offline, pref('messaging.when_away.autorespond', False), not (self.autoresponded))):
  253.             if status.message:
  254.                 self.autoresponded = True
  255.                 import wx
  256.                 
  257.                 def later():
  258.                     if getattr(status, '_a_href', False):
  259.                         content_type = 'text/html'
  260.                     else:
  261.                         content_type = 'text/plain'
  262.                     self.autorespond(status.message, content_type = content_type)
  263.  
  264.                 later = (None, wx.CallAfter)(later)
  265.             
  266.         
  267.  
  268.     
  269.     def __contains__(self, buddy):
  270.         bname = get_bname(buddy)
  271.         buddy = self.buddies[bname]
  272.         return buddy in self.room_list
  273.  
  274.     
  275.     def tingle(self):
  276.         self.system_message('Your digsby sense is tingling!')
  277.  
  278.     
  279.     def buddy(self):
  280.         r = self.other_buddies
  281.         if len(r) == 1:
  282.             return r[0]
  283.         if self.room_list:
  284.             return self.room_list[0]
  285.         return self.self_buddy
  286.  
  287.     buddy = property(buddy)
  288.     
  289.     def other_buddies(self):
  290.         r = self.room_list[:]
  291.         while True:
  292.             
  293.             try:
  294.                 r.remove(self.self_buddy)
  295.             continue
  296.             except ValueError:
  297.                 break
  298.                 continue
  299.             
  300.  
  301.             None<EXCEPTION MATCH>ValueError
  302.         return r
  303.  
  304.     other_buddies = property(other_buddies)
  305.     
  306.     def chat_member_count(self):
  307.         if self.protocol.connected:
  308.             return len(self.room_list)
  309.         return 0
  310.  
  311.     chat_member_count = property(chat_member_count)
  312.     
  313.     def send_typing_status(self, status):
  314.         raise NotImplementedError
  315.  
  316.     did_explicit_exit = False
  317.     
  318.     def exit(self):
  319.         self.unregister_videochat_urlhandler()
  320.  
  321.     
  322.     def explicit_exit(self):
  323.         self.did_explicit_exit = True
  324.         self.exit()
  325.  
  326.     
  327.     def autorespond(self, msg, format = None, **kws):
  328.         if not self.ischat:
  329.             if self.buddy.isbot:
  330.                 log.info('Not sending autoresponse to bot: %r', self.buddy)
  331.                 return None
  332.             if 'has_autotext' not in kws:
  333.                 kws.update(has_autotext = True)
  334.             
  335.             self.send_message(default_formatted_text(AUTORESP + msg), auto = True, **kws)
  336.         
  337.  
  338.     _inwindow = False
  339.     
  340.     def queued_system_messages(self):
  341.         
  342.         try:
  343.             return self._queued_system_messages
  344.         except AttributeError:
  345.             self._queued_system_messages = []
  346.             return self._queued_system_messages
  347.  
  348.  
  349.     queued_system_messages = property(queued_system_messages)
  350.     
  351.     def play_queued_messages(self):
  352.         self._inwindow = True
  353.         if hasattr(self, '_queued_system_messages'):
  354.             
  355.             try:
  356.                 for kws in self._queued_system_messages:
  357.                     traceguard.__enter__()
  358.                     
  359.                     try:
  360.                         self.system_message(**kws)
  361.                     finally:
  362.                         pass
  363.  
  364.             finally:
  365.                 del self._queued_system_messages[:]
  366.  
  367.         
  368.  
  369.     
  370.     def buddy_join(self, buddy):
  371.         if self.ischat:
  372.             self._presence_message(_(u'%s joined the group chat') % buddy.name)
  373.         
  374.  
  375.     
  376.     def buddy_leave(self, buddy):
  377.         if self.ischat and buddy is not self.protocol.self_buddy:
  378.             self._presence_message(_(u'%s left the group chat') % buddy.name)
  379.         
  380.  
  381.     
  382.     def received_native_videochat_request(self, vidoechat_response_callback = None):
  383.         log.info('native_video_chat_request')
  384.         urlarg = 'makeavcall/%s' % id(self)
  385.         if self.videochat_urlhandler is None:
  386.             
  387.             def videochat_urlhandler():
  388.                 if vidoechat_response_callback is not None:
  389.                     vidoechat_response_callback(False)
  390.                 
  391.                 self.send_generic_videochat_request()
  392.  
  393.             self.videochat_urlhandler = (urlarg, videochat_urlhandler)
  394.             urlhandler.register(*self.videochat_urlhandler)
  395.         
  396.         link = 'digsby://%s' % urlarg
  397.         msg = _('%(name)s wants to have an Audio/Video chat. <a href="%(link)s">Send them an invite.</a>') % dict(name = self.buddy.name, link = link)
  398.         self.important_system_message(msg, content_type = 'text/html')
  399.  
  400.     
  401.     def send_generic_videochat_request(self):
  402.         VideoChat = VideoChat
  403.         import digsby.videochat
  404.         VideoChat(self.buddy)
  405.  
  406.     
  407.     def unregister_videochat_urlhandler(self):
  408.         if self.videochat_urlhandler != None:
  409.             urlhandler.unregister(*self.videochat_urlhandler)
  410.             self.videochat_urlhandler = None
  411.         
  412.  
  413.     
  414.     def _presence_message(self, msg):
  415.         kws = dict(message = msg, content_type = 'text/plain', linkify = False)
  416.         if self._inwindow:
  417.             self.system_message(**kws)
  418.         else:
  419.             self.queued_system_messages.append(kws)
  420.  
  421.  
  422.  
  423. def default_formatted_text(msg):
  424.     fmtstr = fmtstr
  425.     import util.primitives.fmtstr
  426.     get_default_format = get_default_format
  427.     import gui.uberwidgets.formattedinput
  428.     return fmtstr.singleformat(msg, get_default_format())
  429.  
  430. if __name__ == '__main__':
  431.     convo = Conversation()
  432.     
  433.     def convo_changed(source, attr, old, new):
  434.         print attr, old, new
  435.  
  436.     convo.add_observer(convo_changed)
  437.     convo.last_message = 'test message'
  438.  
  439.