home *** CD-ROM | disk | FTP | other *** search
/ Maximum CD 2011 February / maximum-cd-2011-02.iso / DiscContents / digsby_setup85.exe / lib / gui / imwin / imhub.pyo (.txt) < prev    next >
Encoding:
Python Compiled Bytecode  |  2010-11-24  |  18.6 KB  |  591 lines

  1. # Source Generated with Decompyle++
  2. # File: in.pyo (Python 2.6)
  3.  
  4. from __future__ import with_statement
  5. import hooks
  6. import wx
  7. from wx import GetTopLevelWindows, GetTopLevelParent, WXK_CONTROL, GetKeyState, CallLater
  8. FindFocus = wx.Window.FindFocus
  9. import threading
  10. import gui.native.helpers as helpers
  11. from util import strip_html2, odict, traceguard
  12. from util.primitives.funcs import Delegate
  13. from util.primitives.fmtstr import fmtstr
  14. from util.lrucache import lru_cache
  15. from common.notifications import fire
  16. from common.sms import normalize_sms as smsize
  17. from common.sms import validate_sms
  18. from common import profile, pref
  19. from gui.imwin.imwin_gui import ImWinPanel
  20. from traceback import print_exc
  21. from logging import getLogger
  22. log = getLogger('imhub')
  23. LOG = log.debug
  24. from gui.uberwidgets.formattedinput import get_default_format
  25. strip_html2 = lru_cache(80)(strip_html2)
  26.  
  27. def is_system_message(messageobj):
  28.     if messageobj is not None:
  29.         pass
  30.     return messageobj.buddy is None
  31.  
  32.  
  33. def is_announcement(message):
  34.     buddy = getattr(message, 'buddy', None)
  35.     if buddy is not None and buddy.service == 'digsby':
  36.         pass
  37.     return buddy.name == 'digsby.org'
  38.  
  39.  
  40. def on_status(status, on_done = None):
  41.     for imwin in ImWinPanel.all():
  42.         if imwin.Buddy == status.buddy:
  43.             wx.CallAfter(imwin.show_status, status, on_done)
  44.             break
  45.             continue
  46.     
  47.  
  48.  
  49. def show_announce_window(message):
  50.     AnnounceWindow = AnnounceWindow
  51.     import gui.imwin.imwin_gui
  52.     announce = AnnounceWindow(wx.FindWindowByName('Buddy List'))
  53.     announce.message(message)
  54.     wx.CallAfter(announce.Show)
  55.  
  56.  
  57. def show_announce_window_After(message):
  58.     wx.CallAfter(show_announce_window, message)
  59.  
  60. hooks.register('digsby.server.announcement', show_announce_window_After)
  61.  
  62. def pre_message_hook(message):
  63.     if is_announcement(message):
  64.         if profile.account_manager.all_accounts:
  65.             show_announce_window(message)
  66.         
  67.         return False
  68.  
  69. im_show = Delegate()
  70.  
  71. def frame_show(frame, show, no_activate = False):
  72.     if show and getattr(frame, '_starting_minimized', False):
  73.         frame.Iconize(True)
  74.         frame._starting_minimized = False
  75.     elif no_activate:
  76.         frame.ShowNoActivate(show)
  77.     else:
  78.         frame.Show(show)
  79.  
  80.  
  81. def on_message(messageobj = None, convo = None, raisenow = False, meta = None, mode = 'im', firenots = True):
  82.     global im_show, im_show, im_show, im_show, im_show, im_show, im_show
  83.     thread_check()
  84.     ImFrame = ImFrame
  85.     import gui.imwin.imtabs
  86.     convo = None if messageobj is not None else convo
  87.     sms = None if messageobj is not None else False
  88.     if not sms:
  89.         pass
  90.     sms = getattr(convo.buddy, 'sms', False)
  91.     if pre_message_hook(messageobj) is False:
  92.         return None
  93.     system_message = is_system_message(messageobj)
  94.     (win, isnew) = None if not raisenow else pre_message_hook(messageobj) is False(window_for, convo = 'meta', meta = 'sms', sms = 'system_message', system_message = 'focus' if raisenow else None, mode = mode)
  95.     if win is None:
  96.         return None
  97.     if firenots:
  98.         fire_notifications(messageobj, win, isnew, mode)
  99.     
  100.     flashnow = True
  101.     frame = GetTopLevelParent(win)
  102.     focusedImFrame = isinstance(focused_top(), ImFrame)
  103.     if isnew:
  104.         if raisenow and not focusedImFrame:
  105.             (im_show,) += (lambda : log.info('calling frame.Show on frame at %r', frame.Rect))
  106.             (im_show,) += (lambda : (wx.CallAfter,)((lambda : frame_show(frame, True)))
  107. )
  108.         elif not frame.IsShown():
  109.             (im_show,) += (lambda : log.info('calling frame.ShowNoActivate on frame at %r', frame.Rect))
  110.             (im_show,) += (lambda : (wx.CallAfter,)((lambda : frame_show(frame, True, no_activate = True)))
  111. )
  112.         
  113.     
  114.     if not focusedImFrame:
  115.         if (raisenow or isnew) and 'stealfocus' == new_action():
  116.             (im_show,) += (lambda : log.info('raising existing IM frame at %r', frame.Rect))
  117.             (None, im_show) += (lambda : raise_imwin(frame, win))
  118.         elif flashnow and messageobj is not None and not win.IsActive():
  119.             bud = messageobj.buddy
  120.             if bud is not None and bud is not messageobj.conversation.self_buddy:
  121.                 (im_show,) += (lambda : wx.CallAfter(win.Notify))
  122.             
  123.         
  124.     if not pref('fullscreen.hide_convos', True) and helpers.FullscreenApp():
  125.         im_show.call_and_clear()
  126.     else:
  127.         log.info('im_hub.on_message ignoring for now because of fullscreen (delegate is %d messages long)', len(im_show))
  128.         helpers.FullscreenAppLog()
  129.     win.message(messageobj, convo, mode, meta)
  130.     return win
  131.  
  132.  
  133. def focused_top():
  134.     focused = FindFocus()
  135.     if focused is not None:
  136.         return focused.Top
  137.  
  138.  
  139. def raise_imwin(frame, imwin):
  140.     log.info('raise_imwin: %r %r', frame, imwin)
  141.     if frame.IsIconized():
  142.         frame.Iconize(False)
  143.         event = wx.IconizeEvent(frame.Id, False)
  144.         frame.AddPendingEvent(event)
  145.     
  146.     frame.ReallyRaise()
  147.     tab = imwin.Tab
  148.     if tab is not None:
  149.         tab.SetActive(True)
  150.     
  151.  
  152.  
  153. def open(idstr):
  154.     contact = profile.blist.contact_for_idstr(idstr)
  155.     if contact is not None:
  156.         return begin_conversation(contact)
  157.  
  158.  
  159. def begin_conversation(contact, mode = 'im', forceproto = False):
  160.     thread_check()
  161.     MetaContact = MetaContact
  162.     OfflineBuddy = OfflineBuddy
  163.     import contacts.metacontacts
  164.     if isinstance(contact, OfflineBuddy):
  165.         log.info('cannot open an IM window for OfflineBuddy %r', contact)
  166.         return None
  167.     meta = isinstance(contact, OfflineBuddy) if isinstance(contact, MetaContact) else None
  168.     if forceproto:
  169.         proto = contact.protocol
  170.     else:
  171.         (contact, proto) = profile.blist.get_from(contact)
  172.     if proto is None:
  173.         log.info('cannot open an IM window for %r, no compatible protocols?', contact)
  174.         return None
  175.     convo = proto.convo_for(contact)
  176.     if contact.sms and not profile.blist.on_buddylist(contact):
  177.         mode = 'sms'
  178.     
  179.     pop_any_hidden(contact)
  180.     return on_message(convo = convo, raisenow = True, meta = meta, mode = mode)
  181.  
  182.  
  183. def window_for(convo, meta = None, sms = False, system_message = False, focus = None, mode = 'im'):
  184.     (win, meta) = find_window_for(convo, meta, sms, system_message)
  185.     if win is not None:
  186.         return (win, False)
  187.     if sms and not profile.blist.on_buddylist(convo.buddy):
  188.         convo = window_for_sms(convo)
  189.     
  190.     if system_message:
  191.         return (None, None)
  192.     win = create_imwin(convo, meta, sms, focus, mode)
  193.     return (win, True)
  194.  
  195.  
  196. def find_window_for(convo, meta = None, sms = False, system_message = False):
  197.     thread_check()
  198.     if meta is None:
  199.         metas = None if not convo.ischat else []
  200.         if metas:
  201.             meta = list(metas)[0]
  202.         
  203.     else:
  204.         metas = [
  205.             meta]
  206.     return (search_for_buddy(metas, convo, sms), meta)
  207.  
  208.  
  209. def search_for_buddy(metas, convo, sms):
  210.     for win in ImWinPanel.all():
  211.         traceguard.__enter__()
  212.         
  213.         try:
  214.             c = win.Conversation
  215.             if c is convo:
  216.                 LOG('direct conversation object match: win: %r, convo: %r', win, convo)
  217.                 return win
  218.             if convo.ischat != win.convo.ischat:
  219.                 continue
  220.             
  221.             winbud = win.Buddy
  222.             if winbud is None:
  223.                 continue
  224.             
  225.             for meta in metas:
  226.                 for contact in meta:
  227.                     if winbud == contact:
  228.                         LOG('matched %r with %r', winbud, contact)
  229.                         return win
  230.                 
  231.                 for contact in meta:
  232.                     if winbud.name == contact.name and winbud.protocol.name == contact.protocol.name:
  233.                         LOG('loosely matched %r with %r', winbud, contact)
  234.                         return win
  235.                 
  236.             
  237.             if winbud.info_key == convo.buddy.info_key:
  238.                 return win
  239.         finally:
  240.             pass
  241.  
  242.     
  243.  
  244.  
  245. def window_for_sms(convo):
  246.     log.info('window_for_sms: %r', convo)
  247.     thread_check()
  248.     buddy_sms = smsize(convo.buddy.name)
  249.     keys = []
  250.     for infokey, infodict in profile.blist.info.iteritems():
  251.         
  252.         try:
  253.             sms_numbers = infodict['sms']
  254.         except KeyError:
  255.             continue
  256.  
  257.         for s in list(sms_numbers):
  258.             
  259.             try:
  260.                 sms = smsize(s)
  261.             except ValueError:
  262.                 log.critical("invalid SMS number in infodict[%r]['sms']: %r", infokey, s)
  263.                 sms_numbers.remove(s)
  264.                 continue
  265.  
  266.             if buddy_sms == sms:
  267.                 keys += [
  268.                     infokey]
  269.                 continue
  270.         
  271.     
  272.     if not keys:
  273.         log.info('no matching sms numbers found')
  274.         return convo
  275.     conn = convo.protocol
  276.     for key in keys:
  277.         if key.startswith('Metacontact #'):
  278.             continue
  279.         
  280.         (buddyname, proto) = info_key_tuple(key)
  281.         if conn.protocol == proto and conn.has_buddy(buddyname):
  282.             return conn.convo_for(conn.get_buddy(buddyname))
  283.     
  284.     return convo
  285.  
  286.  
  287. def new_action():
  288.     return pref('conversation_window.new_action')
  289.  
  290.  
  291. def create_imwin(convo, meta, sms, focus = None, mode = 'im'):
  292.     global im_show, im_show
  293.     thread_check()
  294.     ImFrame = ImFrame
  295.     import gui.imwin.imtabs
  296.     f = None
  297.     hooks.notify('imwin.created')
  298.     focus = None if focus is None else focus
  299.     if pref('messaging.tabs.ctrl_new_window', True):
  300.         pass
  301.     ctrlDown = GetKeyState(WXK_CONTROL)
  302.     if not ctrlDown and pref('messaging.tabs.enabled', True):
  303.         for win in GetTopLevelWindows():
  304.             if isinstance(win, ImFrame):
  305.                 f = win
  306.                 if f.IsActive():
  307.                     focus = False
  308.                 
  309.                 break
  310.                 continue
  311.         
  312.     
  313.     if isinstance(focused_top(), ImFrame):
  314.         focus = False
  315.     
  316.     if getattr(wx.Window.FindFocus(), 'click_raises_imwin', False) and wx.LeftDown():
  317.         focus = True
  318.     
  319.     if f is None:
  320.         if pref('messaging.tabs.enabled', True):
  321.             id = ''
  322.         elif meta is not None:
  323.             pass
  324.         
  325.         id = convo.buddy.idstr()
  326.         f = ImFrame(startMinimized = not focus, posId = id)
  327.     
  328.     w = ImWinPanel(f)
  329.     if convo is not None:
  330.         w.set_conversation(convo, meta)
  331.     
  332.     if focus:
  333.         (None, im_show) += (lambda : raise_imwin(f, w))
  334.         (im_show,) += (lambda : w.FocusTextCtrl())
  335.     
  336.     tab = f.AddTab(w, focus = focus)
  337.     if hasattr(tab, 'OnActive'):
  338.         tab.OnActive += w.FocusTextCtrl
  339.     
  340.     hooks.notify('digsby.statistics.imwin.imwin_created')
  341.     return w
  342.  
  343.  
  344. def fire_notifications(msg, win, isnew, mode, hidden = False):
  345.     if msg is None or msg.buddy is None:
  346.         return []
  347.     convo = msg.conversation
  348.     bud = msg.buddy
  349.     
  350.     def stop_notify(win = (None, msg.buddy is None, win)):
  351.         if win:
  352.             
  353.             try:
  354.                 win.Unnotify()
  355.             except wx.PyDeadObjectError:
  356.                 pass
  357.  
  358.             if not (win.Top.AnyNotified) and pref('conversation_window.notify_flash'):
  359.                 win.Top.StopFlashing()
  360.             
  361.         
  362.         if hidden and pref('messaging.popups.close_dismisses_hidden', False):
  363.             _remove_hidden_message(bud, msg)
  364.         
  365.  
  366.     if msg.get('content_type', 'text/html') in ('text/html', 'text/xhtml'):
  367.         
  368.         try:
  369.             popup_message = strip_html2(msg.message).decode('xml')
  370.         except Exception:
  371.             print_exc()
  372.             popup_message = msg.message
  373.         except:
  374.             None<EXCEPTION MATCH>Exception
  375.         
  376.  
  377.     None<EXCEPTION MATCH>Exception
  378.     popup_message = msg.message
  379.     fire_opts = dict(buddy = bud, onuserclose = stop_notify)
  380.     if convo is not None:
  381.         pass
  382.     ischat = convo.ischat
  383.     if ischat:
  384.         skin = skin
  385.         import gui
  386.         fire_opts.update(header = _('Group Chat (%d)') % convo.chat_member_count, msg = _('%s: %s') % (bud.alias, popup_message), icon = skin.get('ActionsBar.Icons.RoomList', None), popupid = 'chat!!!%r!!!%r' % (convo.protocol.name, convo.chat_room_name))
  387.     elif bud is not None:
  388.         pass
  389.     
  390.     fire_opts.update(msg = popup_message, icon = convo.icon, popupid = msg.buddy.idstr())
  391.     if bud is not None:
  392.         
  393.         def click_popup(text):
  394.             if pop_any_hidden(bud):
  395.                 return None
  396.             if convo.ischat:
  397.                 on_message(convo = convo, raisenow = True)
  398.             else:
  399.                 begin_conversation(bud)
  400.             if win:
  401.                 
  402.                 try:
  403.                     val = win.input_area.Value
  404.                 except wx.PyDeadObjectError:
  405.                     pass
  406.  
  407.                 if not val:
  408.                     win.input_area.Value = text
  409.                     wx.CallAfter(win.TextCtrl.SetInsertionPointEnd)
  410.                 
  411.             
  412.  
  413.         fire_opts.update(onclick = click_popup)
  414.     
  415.     notification = _get_notification_types(bud, convo, win, hidden, isnew)
  416.     
  417.     def send_from_popup(text, options, convo = convo, win = win, opts = (fire_opts.copy(),)):
  418.         if not text:
  419.             return None
  420.         CallLater(200, stop_notify)
  421.         convo.send_message(fmtstr.singleformat(text, format = _get_format(win)))
  422.         if not wx.GetKeyState(wx.WXK_CONTROL):
  423.             return '> ' + text
  424.  
  425.     fire_opts['input'] = send_from_popup
  426.     return fire(notification, **fire_opts)
  427.  
  428.  
  429. def _get_notification_types(bud, convo, win, hidden, isnew):
  430.     if bud is convo.self_buddy:
  431.         notification = 'message.sent'
  432.     elif hidden:
  433.         notification = [
  434.             'message.received.hidden']
  435.         if isnew:
  436.             notification.append('message.received.initial')
  437.         
  438.     elif isnew:
  439.         notification = 'message.received.initial'
  440.     elif not win and not win.IsActive() and not wx.GetApp().IsActive() or win.Mode not in ('im', 'sms'):
  441.         notification = 'message.received.background'
  442.     else:
  443.         notification = 'message.received'
  444.     return notification
  445.  
  446.  
  447. def _get_format(win):
  448.     format = None
  449.     if win:
  450.         
  451.         try:
  452.             format = win.input_area.Format
  453.         except wx.PyDeadObjectError:
  454.             pass
  455.         except Exception:
  456.             print_exc()
  457.         except:
  458.             None<EXCEPTION MATCH>wx.PyDeadObjectError
  459.         
  460.  
  461.     None<EXCEPTION MATCH>wx.PyDeadObjectError
  462.     if format is None:
  463.         format = get_default_format()
  464.     
  465.     return format
  466.  
  467.  
  468. def show_info(buddy):
  469.     begin_conversation(buddy, mode = 'info')
  470.  
  471.  
  472. def thread_check():
  473.     if threading.currentThread().getName() != 'MainThread':
  474.         raise Exception('imhub methods must be called on the main GUI thread')
  475.     threading.currentThread().getName() != 'MainThread'
  476.  
  477.  
  478. def info_key_tuple(info_key):
  479.     i = info_key.find('_')
  480.     if i == -1:
  481.         pass
  482.     
  483.     return (info_key[:i], info_key[i + 1:])
  484.  
  485. hidden_windows = odict()
  486.  
  487. def hidden_count():
  488.     return len(hidden_windows)
  489.  
  490.  
  491. def hidden_convo_contacts():
  492.     return hidden_windows.keys()
  493.  
  494.  
  495. def hide_message(messageobj, meta, sms, system_message):
  496.     if messageobj is None:
  497.         return (False, False)
  498.     convo = messageobj.conversation
  499.     if new_action() != 'hide':
  500.         return (False, False)
  501.     (win, meta) = find_window_for(convo, meta, sms, system_message)
  502.     if win is not None:
  503.         return (False, False)
  504.     if not meta:
  505.         pass
  506.     ident = convo.buddy.info_key
  507.     _notify_hidden()
  508.     return (True, isnew)
  509.  
  510.  
  511. def pop_all_hidden():
  512.     for contact in list(hidden_windows.keys()):
  513.         pop_any_hidden(contact)
  514.     
  515.  
  516.  
  517. def pop_any_hidden(contact, notify = True):
  518.     quiet_log_messages = quiet_log_messages
  519.     import gui.imwin.messagearea
  520.     all_messages = get_any_hidden(contact)
  521.     if not all_messages:
  522.         return None
  523.     quiet_log_messages(all_messages).__enter__()
  524.     
  525.     try:
  526.         for messageobj in all_messages:
  527.             traceguard.__enter__()
  528.             
  529.             try:
  530.                 on_message(messageobj, raisenow = True, firenots = False)
  531.             finally:
  532.                 pass
  533.  
  534.     finally:
  535.         pass
  536.  
  537.  
  538.  
  539. def get_any_hidden(contact, pop = True):
  540.     keys = hidden_windows.keys()
  541.     if not keys:
  542.         return []
  543.     contacts = set()
  544.     if not isinstance(contact, basestring):
  545.         contacts.update((lambda .0: for m in .0:
  546. m.info_key)(profile.metacontacts.forbuddy(contact)))
  547.     
  548.     contact = getattr(contact, 'info_key', contact)
  549.     contacts.add(contact)
  550.     all_messages = []
  551.     for message_list in hidden_windows.values():
  552.         all_messages.extend(message_list)
  553.     
  554.     messages = []
  555.     for c in keys:
  556.         if c in contacts:
  557.             if pop:
  558.                 msgs = hidden_windows.pop(c, [])
  559.             else:
  560.                 msgs = hidden_windows.get(c, [])
  561.             messages.extend(msgs)
  562.             continue
  563.     
  564.     return messages
  565.  
  566.  
  567. def _remove_hidden_message(contact, message):
  568.     contact = getattr(contact, 'info_key', contact)
  569.     
  570.     try:
  571.         messages = hidden_windows[contact]
  572.     except KeyError:
  573.         return False
  574.  
  575.     
  576.     try:
  577.         messages.remove(message)
  578.     except ValueError:
  579.         return False
  580.  
  581.     if len(messages) == 0:
  582.         hidden_windows.pop(contact)
  583.         _notify_hidden()
  584.     
  585.     return True
  586.  
  587.  
  588. def _notify_hidden():
  589.     hooks.notify('digsby.im.message_hidden', hidden_windows)
  590.  
  591.