Exemplo n.º 1
0
def each(hook_identifier, *a, **k):
    impls = k.pop('impls', [k.pop('impl', None)])
    for impl in impls:
        for hook in Hook(hook_identifier, impl):
            try:
                yield hook(*a, **k)
            except Exception:
                traceback.print_exc()
Exemplo n.º 2
0
def get_image_load_paths(paths):
    'Returns a list of paths from which skin images can be loaded.'

    image_load_paths = [p.parent for p in paths]

    for pathhook in Hook('digsby.skin.load.skinpaths'):
        hook_paths = pathhook()
        if hook_paths is not None:
            image_load_paths.extend(hook_paths)

    return image_load_paths
Exemplo n.º 3
0
def syn(identifier, *args, **kwargs):
    ret = True

    for hook in Hook(identifier):
        #_log.info('HOOK: %s',repr(hook))
        try:
            ret = hook(*args, **kwargs)
            if not ret:
                ret = False
        except Exception:
            traceback.print_exc()
    return ret
Exemplo n.º 4
0
def first(hook_identifier, *a, **k):
    impls = k.pop('impls', [k.pop('impl', None)])
    raise_exceptions = k.pop('raise_hook_exceptions', False)

    for impl in impls:
        for hook in Hook(hook_identifier, impl=impl):
            try:
                v = hook(*a, **k)
                if v is not None:
                    return v
            except Exception:
                if raise_exceptions:
                    raise

                traceback.print_exc()

    return None
Exemplo n.º 5
0
def reduce(hook_identifier, arg, *args, **kwargs):
    '''
    Passes arg to the first Hook found for hook_identifier. The return value
    of that hook goes to the next hook, and so on. The return value of the
    last Hook becomes the return value of this function.
    '''
    raise_exceptions = kwargs.pop('raise_exceptions', False)
    impls = kwargs.pop('impls', [kwargs.pop('impl', None)])
    for impl in impls:
        for hook in Hook(hook_identifier, impl):
            if raise_exceptions:
                arg = hook(arg, *args, **kwargs)
            else:
                try:
                    arg = hook(arg, *args, **kwargs)
                except Exception:
                    traceback.print_exc()
    return arg
Exemplo n.º 6
0
def group_profile_statuses():
    msgs = sorted((c for c in profile.statuses), key=lambda msg: msg.away)

    j = -1
    for j, msg in enumerate(msgs):
        if msg.away: break
    else:
        j = -1

    if j == -1:
        j = len(msgs)

    avail_msgs = msgs[:j]
    avail_msgs.insert(0, StatusMessage.Available.copy())

    away_msgs = msgs[j:]
    away_msgs.insert(0, StatusMessage.Away.copy())
    return avail_msgs, away_msgs, filter(
        None, [s() for s in Hook('digsby.im.statusmessages')])
Exemplo n.º 7
0
    def on_status_messages_changed(self, *a):
        '''
        Invoked when a status message changes, or the user status list changes.

        Rebuilds the status menu items.
        '''
        log.info('on_status_messages_changed, updating menu')

        self.RemoveAllItems()
        additem = self.additem

        def add_status_item(pname, name):
            additem([skin.get('statusicons.%s' % pname), name],
                    method=getattr(self, 'on_' + pname))

        # Available
        add_status_item('available', _('Available'))

        # user statuses
        self.sortedstatuses = msgs = sorted([c for c in profile.statuses],
                                            key=lambda msg: msg.away)

        # Find where to insert the special "Away" status item
        j = -1
        found = False
        for j, msg in enumerate(msgs):
            if msg.away:
                found = True
                break

        for i, msg in enumerate(msgs):
            if found and i == j:
                add_status_item('away', _('Away'))
            online_image = skin.get(
                'statusicons.away' if msg.away else 'statusicons.available')
            additem([online_image, msg.title],
                    method=lambda mi, msg=msg: self.setandshow(msg),
                    id=i)

        if not found or j == -1:
            add_status_item('away', _('Away'))

        # Custom...
        additem(_('Custom...'), method=self.on_custom)
        self.AppendSeparator()
        if global_status_enabled():
            additem([skin.get('icons.globalstatus'),
                     _('Global Status')],
                    method=self.on_global)

        log.info('updating status menu with %d extra statuses',
                 len(Hook('digsby.im.statusmessages')))
        for msg in Hook('digsby.im.statusmessages'):
            message = msg()
            if message is None:
                continue
            additem([message.icon, message.title],
                    method=lambda mi, msg=msg: self.setandshow(msg()))

        if global_status_enabled():
            additem([skin.get('statusicons.promote'),
                     _('Promote Digsby!')],
                    method=self.on_promote)

        # Invisible
        additem([skin.get('statusicons.invisible'),
                 _('Invisible')], self.on_invisible)

        # Offline
        self.offline_item = None
        self.on_offline_allowed()
Exemplo n.º 8
0
    def __init__(self,
                 parent,
                 buddylist,
                 statuses,
                 get_status_method=get_profile_status,
                 set_status_method=set_profile_status):
        '''
        StatusCombo constructor.

        parent   - a wx.Window parent window
        statuses - an observable list of StatusMessage objects
        '''

        self.buddylist = buddylist
        self.buddylist.Bind(wx.EVT_KEY_DOWN, self.on_buddylist_key)
        self.searching = False
        self.searchHintShown = False

        if not getattr(StatusCombo, 'searchThresholdRegistered',
                       False) and pref('search.buddylist.show_hint', True):

            def SearchThresholdReached(*a, **k):
                if pref('search.buddylist.show_hint', True):
                    setpref('search.buddylist.show_hint', False)

            Hook('digsby.achievements.threshold',
                 'buddylist.search').register(SearchThresholdReached)
            StatusCombo.searchThresholdRegistered = True

        self.offline_item = None
        self.get_profile_status = get_status_method
        self.set_profile_status = set_status_method

        status = self.get_profile_status()

        UberCombo.__init__(self,
                           parent,
                           skinkey='combobox',
                           typeable=True,
                           valuecallback=self.on_text_lose_focus,
                           empty_text=getattr(status, 'hint',
                                              status.title.title()),
                           maxmenuheight=15)

        self.buttoncallback = self.on_status_button
        self.cbutton = UberButton(self, -1, skin=self.cbuttonskin)
        self.cbutton.Bind(wx.EVT_BUTTON, self._on_left_button)
        self.content.Insert(0, self.cbutton, 0, wx.EXPAND)

        self.cbutton.BBind(RIGHT_UP=self.on_status_button_right_click,
                           LEFT_DOWN=self.on_status_button_left_click,
                           LEFT_UP=self.on_status_button_left_up)

        self.display.Bind(
            wx.EVT_LEFT_DOWN, lambda e:
            (e.Skip(), setattr(self, 'oldValue', self.Value)))

        # the on_allow_status_changes method is called when the list of connected
        # im accounts changes size. if all accounts are offline this control
        # becomes disabled..

        #profile.account_manager.connected_accounts.add_observer(self.on_allow_status_changes)
        profile.account_manager.connected_accounts.add_observer(
            self.on_offline_allowed, obj=self)

        # Listen on status messages (changes, additions, deletes).
        _obs_link = statuses.add_list_observer(self.on_status_messages_changed,
                                               self.on_status_messages_changed)
        self.Bind(
            wx.EVT_WINDOW_DESTROY, lambda e:
            (log.info('status combo removing observers'), e.Skip(),
             _obs_link.disconnect()))

        self.on_status_messages_changed(statuses)

        # when the profile's status changes, update to reflect it
        profile.add_observer(self.on_profile_status_changed, 'status')

        # Display the current status.
        self.show_status(self.get_profile_status())

        # Timer for committing status messages after a delay.
        self.timer = wx.PyTimer(self.SetFocus)
        self.Bind(wx.EVT_TEXT, self.on_typing)

        self.button_timer = wx.PyTimer(self.on_status_button_right_click)

        textbind = self.TextField.Bind
        textbind(wx.EVT_SET_FOCUS, lambda e: setattr(self, 'skipenter', False))
        textbind(wx.EVT_KEY_DOWN, self._on_key_down)
        textbind(wx.EVT_TEXT_ENTER, self._on_enter)

        self.DropDownButton.Bind(wx.EVT_LEFT_DOWN, self._dbutton_left)

        self.OnActivateSearch = Delegate()
        self.OnDeactivateSearch = Delegate()
Exemplo n.º 9
0
def create_main_menu(parent):
    'Returns the main menu object.'

    menu = MenuBar(parent, skinkey='menubar')
    digsby = Menu(parent)
    view = Menu(parent)
    tools = Menu(parent)
    help = Menu(parent)

    def makeadd(m):
        return (lambda title, callback=None, id=-1: m.AddItem(
            title, callback=callback, id=id))

    #
    # My Status
    #
    mystatus = Menu(parent, onshow=update_statuses)
    add = makeadd(mystatus)
    add(_('&New Status Message...'), new_status_message)
    add(_('&Edit Status Messages...'), lambda: prefsdialog_show('status'))
    mystatus.AddSep()

    from gui.protocols import add_group

    def add_chat():
        import gui.chatgui
        gui.chatgui.join_chat()

    #
    # Digsby
    #
    digsby.AddSubMenu(mystatus, _('My Status'))
    add = makeadd(digsby)
    add(_('My &Accounts...'), lambda: prefsdialog_show('accounts'))
    digsby.AddSep()
    sendimitem = add(_('&New IM...\tCtrl+N'), ShowNewIMDialog)
    if pref('messaging.groupchat.enabled', False):
        groupchatitem = add(_('New Group C&hat...\tCtrl+Shift+N'), add_chat)
    else:
        groupchatitem = None
    digsby.AddSep()
    addcontactitem = add(_('Add &Contact...\tCtrl+A'),
                         lambda: AddContactDialog.MakeOrShow())
    addgroupitem = add(_('Add &Group...\tCtrl+Shift+A'), lambda: add_group())
    renameitem = add(_('&Rename Selection'),
                     lambda: parent.blist.rename_selected())
    deleteitem = add(
        _('&Delete Selection...'),
        lambda: parent.blist.delete_blist_item(parent.blist.SelectedItem))
    digsby.AddSep()
    add(_('Sign &Off Digsby (%s)') % profile.name, lambda: profile.signoff())
    # wx.App handles this for proper shutdown.
    add(_('E&xit Digsby'), id=wx.ID_EXIT)

    def on_digsby_show(_m):
        b = parent.blist.SelectedItem

        allow_add = any(x.allow_contact_add
                        for x in profile.account_manager.connected_accounts)

        for item in (sendimitem, groupchatitem, addcontactitem, addgroupitem):
            if item is not None:
                item.Enable(allow_add)

        if not allow_rename(b):
            renameitem.SetItemLabel(_('&Rename Selection'))
            deleteitem.SetItemLabel(_('&Delete Selection'))
            renameitem.Enable(False)
            deleteitem.Enable(False)
        else:
            renameitem.SetItemLabel(
                _('&Rename {name}').format(name=getattr(b, 'alias', b.name)))
            deleteitem.SetItemLabel(
                _('&Delete {name}').format(name=getattr(b, 'alias', b.name)))
            renameitem.Enable(True)
            deleteitem.Enable(True)

    #
    # View
    #

    add = makeadd(view)
    view.AddPrefCheck('buddylist.always_on_top', _('&Always On Top'))
    add(_('Skins...\tCtrl+S'), lambda: prefsdialog_show('appearance'))
    view.AddSep()
    view.AddPrefCheck('buddylist.show_menubar', _('&Menu Bar'))

    def on_menubar(val):
        if not val:
            wx.MessageBox(
                _('You can bring back the menubar by right clicking '
                  'on the digsby icon in the task tray.'), _('Hide Menu Bar'))

    profile.prefs.link('buddylist.show_menubar',
                       lambda val: wx.CallAfter(on_menubar, val), False, menu)

    view.AddPrefCheck('buddylist.show_status', _('Status Panel'))
    add(_('Arrange &Panels...'),
        callback=lambda *_a: edit_buddylist_order(parent))
    view.AddSep()
    view.AddPrefCheck('buddylist.show_mobile',
                      _('Show &Mobile Contacts\tCtrl+M'))
    view.AddPrefCheck('buddylist.show_offline',
                      _('Show &Offline Contacts\tCtrl+O'))
    groupoffline = view.AddPrefCheck('buddylist.group_offline',
                                     _('&Group Offline Contacts\tCtrl+G'))

    hideoffline = view.AddPrefCheck('buddylist.hide_offline_groups',
                                    _('&Hide Offline Groups'))

    groupby = Menu(parent)
    add = makeadd(groupby)
    groupby.sorttypes = []

    # sort by
    sortby = Menu(parent)
    add = makeadd(sortby)
    sortby.sorttypes = []

    sort_models = profile.blist.sort_models
    group_by = sort_models[0]
    sort_by = sort_models[1]
    then_by = sort_models[2]

    def addsort(model, view, sortstr, title):
        def set(model=model, view=view, sortstr=sortstr):
            model.selection = [v[0] for v in model.values].index(sortstr)
            view[model.selection].Check(True)

        mi = view.AddCheckItem(title, set)
        view.sorttypes.append(sortstr)
        return mi

    sort_names = dict(
        (('none', _('&None')), ('status', _('&Status')), ('name', _('N&ame')),
         ('log', _('&Log Size')), ('service', _('Ser&vice'))))

    def addsorts(model, view, names):
        for name in names:
            addsort(model=model,
                    view=view,
                    sortstr=name,
                    title=sort_names[name])

    addsorts(model=group_by,
             view=groupby,
             names=[k for k, _v in GROUP_BY_CHOICES])
    groupby.AddSep()
    groupby.AddItem(_('Advan&ced...'),
                    callback=lambda: prefsdialog_show('contact_list'))

    addsorts(model=sort_by,
             view=sortby,
             names=[k for k, _v in SORT_BY_CHOICES])
    sortby.AddSep()

    def sortby_adv_click():
        sortby[-1].Check(then_by.selection > 0)
        prefsdialog_show('contact_list')

    sortby.AddCheckItem(_('Advan&ced...'), callback=sortby_adv_click)
    sortby_adv = sortby[-1]

    groupby.reset_watcher = reset_checks_SortOptionWatcher(
        model=group_by, view=groupby, names=GROUP_BY_CHOICES)
    sortby.reset_watcher = reset_checks_SortOptionWatcher(
        model=sort_by, view=sortby, names=SORT_BY_CHOICES)
    sortby.adv_watcher = reset_check_AdvWatcher(model=then_by, view=sortby_adv)

    view.AddSep()
    view.AddSubMenu(groupby, _('&Group By'))
    view.AddSubMenu(sortby, _('&Sort By'))

    #
    # Tools
    #

    add = makeadd(tools)
    add(_('&Preferences...\tCtrl+P'),
        id=wx.ID_PREFERENCES,
        callback=lambda: prefsdialog_show('accounts'))
    add(_('Buddy List &Search\tCtrl+F'), parent.start_search)
    add(_('&File Transfer History\tCtrl+J'), FileTransferDialog.Display)

    def pb_show():
        from gui.pastbrowser import PastBrowser
        PastBrowser.MakeOrShow()

    add(_('&Chat History\tCtrl+H'), pb_show)

    #
    # Help
    #
    add = makeadd(help)
    add(_('&Documentation'),
        lambda: wx.LaunchDefaultBrowser('http://wiki.digsby.com'))
    add(_('Support &Forums'),
        lambda: wx.LaunchDefaultBrowser('http://forum.digsby.com'))
    help.AddSep()
    add(_('&Submit Bug Report'), do_diagnostic)
    add(_('Su&ggest a Feature'), send_features_email)
    help.AddSep()

    if getattr(sys, 'DEV', False) or pref('debug.console', False):
        add(_('Show Debug Console'), wx.GetApp().toggle_crust)
        help.AddSep()

    add(_('Su&pport Digsby'), lambda: support.SupportFrame.MakeOrShow(parent))

    for hook in Hook("digsby.help.actions"):
        help_menu_items = hook()
        for item in help_menu_items:
            add(*item)

    def on_view_show(_m):
        sortstatus = pref('buddylist.sortby').startswith('*status')

        showoffline = pref('buddylist.show_offline')
        hidegroups = pref('buddylist.hide_offline_groups')
        groupoff = pref('buddylist.group_offline')

        groupoffline.Enable(not sortstatus and showoffline)
        groupoffline.Check(groupoff and (not sortstatus and showoffline))

        hideoffline.Enable(not sortstatus)
        hideoffline.Check((sortstatus and not showoffline)
                          or (not sortstatus and hidegroups))

    digsbyMenuName = _('&Digsby')
    if config.platformName == "mac":
        digsbyMenuName = _("&File")

    menu.Append(digsby, digsbyMenuName, onshow=on_digsby_show)
    menu.Append(view, _('&View'), onshow=on_view_show)
    menu.Append(tools,
                _('&Tools'),
                onshow=lambda m: on_accounts_entries(parent, m))
    menu.Append(help, _('&Help'))
    return menu
Exemplo n.º 10
0
    def setup(self):
        if self.did_setup:
            warnings.warn('reinitialized AddOn CountTracker')
            return
        self.did_setup = True
        from peak.util.plugins import Hook
        Hook('digsby.im.msg.async',            'stats_counter').register(self.im)

        Hook('digsby.statistics.emoticons.box_viewed', 'stats_counter').register(self.emoticon_box_viewed)
        Hook('digsby.statistics.emoticons.chosen',     'stats_counter').register(self.emoticon_chosen)
        Hook('digsby.video_chat.requested',            'stats_counter').register(self.video_chat_requested)
        Hook('digsby.statistics.sms.sent',  'stats_counter').register(self.sms_sent)

        Hook('digsby.statistics.logviewer.log_viewed', 'stats_counter').register(self.log_viewed)
        Hook('digsby.statistics.prefs.prefs_opened', 'stats_counter').register(self.prefs_opened)
        Hook('digsby.statistics.imwin.imwin_created', 'stats_counter').register(self.imwin_created)
        Hook('digsby.statistics.imwin.imwin_engage', 'stats_counter').register(self.imwin_engage)

        Hook('digsby.statistics.infobox.shown', 'stats_counter').register(self.infobox_shown)

        Hook('digsby.statistics.contact_added', 'stats_counter').register(self.contact_added)
        Hook('digsby.statistics.ui.select_status', 'stats_counter').register(self.ui_select_status)
        Hook('digsby.statistics.ui.dialogs.add_contact.created', 'stats_counter').register(self.contact_add_dialog)


        Hook('digsby.app.exit',                'stats_counter').register(self.flush)

        Hook('digsby.stats_counter.important_threshold', 'stats_counter').register(self.important)

        for hook_name, server_side_name in simple_incrementers:
            Hook(hook_name, 'stats_counter').register(self.self_incrementer(server_side_name))

        Hook('digsby.statistics.feed_ads.citygrid.click_cents', 'stats_counter').register(self.citygrid_click)

        Hook('digsby.research.run_time', 'stats_counter').register(self.research_run_time)
Exemplo n.º 11
0
def register(hook_identifier, cb, impl=None):
    return Hook(hook_identifier, impl).register(cb)
Exemplo n.º 12
0
            trees.append(load_skinfile(f))
        except Exception, e:
            errors.append(e)
            del e
        else:
            successful = True

    if not successful:
        MessageBox('There was an error loading skin "%s":\n\n%s' % (skin, '\n'.join(str(e) for e in errors)),
                   'Skin Error')

    # trees can also be supplied via Hook
    from gui.skin import SkinStorage
    to_skinstorage = dictrecurse(SkinStorage)

    for hook in Hook('digsby.skin.load.trees'):
        hook_trees = hook()

        if hook_trees is not None:
            # transform all mappings provided by plugins into SkinStorage
            # objects
            # TODO: why is dictrecurse not a deepcopy?
            trees[insert_position:insert_position] = (to_skinstorage(deepcopy(t)) for t in hook_trees)

    return trees


def get_image_load_paths(paths):
    'Returns a list of paths from which skin images can be loaded.'

    image_load_paths = [p.parent for p in paths]