Skip to content
Snippets Groups Projects
helpers.py 48.4 KiB
Newer Older
        # our last chance, ask uname and strip it
        uname_output = get_output_of_command('uname -sr')
        if uname_output is not None:
            os_info = uname_output[0] # only first line
            gajim.os_info = os_info
            return os_info
    os_info = 'N/A'
    gajim.os_info = os_info
    return os_info
def allow_showing_notification(account, type_ = 'notify_on_new_message',
                advanced_notif_num = None, is_first_message = True):
    """
    Is it allowed to show nofication?

    Check OUR status and if we allow notifications for that status type is the
    option that need to be True e.g.: notify_on_signing is_first_message: set it
    to false when it's not the first message
    """
    if advanced_notif_num is not None:
        popup = gajim.config.get_per('notifications', str(advanced_notif_num),
                'popup')
        if popup == 'yes':
            return True
        if popup == 'no':
            return False
    if type_ and (not gajim.config.get(type_) or not is_first_message):
        return False
    if gajim.config.get('autopopupaway'): # always show notification
        return True
    if gajim.connections[account].connected in (2, 3): # we're online or chat
        return True
    return False
def allow_popup_window(account, advanced_notif_num = None):
    """
    Is it allowed to popup windows?
    """
    if advanced_notif_num is not None:
        popup = gajim.config.get_per('notifications', str(advanced_notif_num),
                'auto_open')
        if popup == 'yes':
            return True
        if popup == 'no':
            return False
    autopopup = gajim.config.get('autopopup')
    autopopupaway = gajim.config.get('autopopupaway')
    if autopopup and (autopopupaway or \
    gajim.connections[account].connected in (2, 3)): # we're online or chat
        return True
    return False
def allow_sound_notification(account, sound_event, advanced_notif_num=None):
    if advanced_notif_num is not None:
        sound = gajim.config.get_per('notifications', str(advanced_notif_num),
                'sound')
        if sound == 'yes':
            return True
        if sound == 'no':
            return False
    if gajim.config.get('sounddnd') or gajim.connections[account].connected != \
    gajim.SHOW_LIST.index('dnd') and gajim.config.get_per('soundevents',
    sound_event, 'enabled'):
        return True
    return False
    full_jid_with_resource = contact.jid
    if contact.resource:
        full_jid_with_resource += '/' + contact.resource
    highest_contact = gajim.contacts.get_contact_with_highest_priority(
            account, contact.jid)

    # Look for a chat control that has the given resource, or default to
    # one without resource
    ctrl = gajim.interface.msg_win_mgr.get_control(full_jid_with_resource,
            account)

    if ctrl:
        return ctrl
    elif highest_contact and highest_contact.resource and \
    contact.resource != highest_contact.resource:
        return None
    else:
        # unknown contact or offline message
        return gajim.interface.msg_win_mgr.get_control(contact.jid, account)
def get_notification_icon_tooltip_dict():
    """
    Return a dict of the form {acct: {'show': show, 'message': message,
    'event_lines': [list of text lines to show in tooltip]}
    """
    # How many events must there be before they're shown summarized, not per-user
    max_ungrouped_events = 10

    accounts = get_accounts_info()

    # Gather events. (With accounts, when there are more.)
    for account in accounts:
        account_name = account['name']
        account['event_lines'] = []
        # Gather events per-account
        pending_events = gajim.events.get_events(account = account_name)
        messages, non_messages, total_messages, total_non_messages = {}, {}, 0, 0
        for jid in pending_events:
            for event in pending_events[jid]:
                if event.type_.count('file') > 0:
                    # This is a non-messagee event.
                    messages[jid] = non_messages.get(jid, 0) + 1
                    total_non_messages = total_non_messages + 1
                else:
                    # This is a message.
                    messages[jid] = messages.get(jid, 0) + 1
                    total_messages = total_messages + 1
        # Display unread messages numbers, if any
        if total_messages > 0:
            if total_messages > max_ungrouped_events:
                text = ngettext(
                        '%d message pending',
                        '%d messages pending',
                        total_messages, total_messages, total_messages)
                account['event_lines'].append(text)
            else:
                for jid in messages.keys():
                    text = ngettext(
                            '%d message pending',
                            '%d messages pending',
                            messages[jid], messages[jid], messages[jid])
                    contact = gajim.contacts.get_first_contact_from_jid(
                            account['name'], jid)
                    if jid in gajim.gc_connected[account['name']]:
                        text += _(' from room %s') % (jid)
                    elif contact:
                        name = contact.get_shown_name()
                        text += _(' from user %s') % (name)
                    else:
                        text += _(' from %s') % (jid)
                    account['event_lines'].append(text)

        # Display unseen events numbers, if any
        if total_non_messages > 0:
            if total_non_messages > max_ungrouped_events:
                text = ngettext(
Dicson's avatar
Dicson committed
                    '%d event pending',
                    '%d events pending',
                    total_non_messages, total_non_messages,total_non_messages)
                account['event_lines'].append(text)
            else:
                for jid in non_messages.keys():
Dicson's avatar
Dicson committed
                    text = ngettext('%d event pending', '%d events pending',
                        non_messages[jid], non_messages[jid], non_messages[jid])
                    text += _(' from user %s') % (jid)
                    account[account]['event_lines'].append(text)

    return accounts
def get_notification_icon_tooltip_text():
    text = None
    # How many events must there be before they're shown summarized, not per-user
    # max_ungrouped_events = 10
    # Character which should be used to indent in the tooltip.
    indent_with = ' '

    accounts = get_notification_icon_tooltip_dict()

    if len(accounts) == 0:
        # No configured account
        return _('Gajim')

    # at least one account present

    # Is there more that one account?
    if len(accounts) == 1:
        show_more_accounts = False
    else:
        show_more_accounts = True

    # If there is only one account, its status is shown on the first line.
    if show_more_accounts:
        text = _('Gajim')
    else:
        text = _('Gajim - %s') % (get_account_status(accounts[0]))

    # Gather and display events. (With accounts, when there are more.)
    for account in accounts:
        account_name = account['name']
        # Set account status, if not set above
        if (show_more_accounts):
            message = '\n' + indent_with + ' %s - %s'
            text += message % (account_name, get_account_status(account))
            # Account list shown, messages need to be indented more
            indent_how = 2
        else:
            # If no account list is shown, messages could have default indenting.
            indent_how = 1
        for line in account['event_lines']:
            text += '\n' + indent_with * indent_how + ' '
            text += line
    return text

def get_accounts_info():
    """
    Helper for notification icon tooltip
    """
    accounts = []
    accounts_list = sorted(gajim.contacts.get_accounts())
    for account in accounts_list:
        status_idx = gajim.connections[account].connected
        # uncomment the following to hide offline accounts
        # if status_idx == 0: continue
        status = gajim.SHOW_LIST[status_idx]
        message = gajim.connections[account].status
        single_line = get_uf_show(status)
        if message is None:
            message = ''
        else:
            message = message.strip()
        if message != '':
            single_line += ': ' + message
        accounts.append({'name': account, 'status_line': single_line,
                        'show': status, 'message': message})
    return accounts
    if os.path.isdir(os.path.join(gajim.DATA_DIR, 'iconsets', iconset)):
        return os.path.join(gajim.DATA_DIR, 'iconsets', iconset)
    elif os.path.isdir(os.path.join(gajim.MY_ICONSETS_PATH, iconset)):
        return os.path.join(gajim.MY_ICONSETS_PATH, iconset)
js's avatar
js committed
def get_mood_iconset_path(iconset):
    if os.path.isdir(os.path.join(gajim.DATA_DIR, 'moods', iconset)):
        return os.path.join(gajim.DATA_DIR, 'moods', iconset)
    elif os.path.isdir(os.path.join(gajim.MY_MOOD_ICONSETS_PATH, iconset)):
        return os.path.join(gajim.MY_MOOD_ICONSETS_PATH, iconset)
js's avatar
js committed

js's avatar
js committed
def get_activity_iconset_path(iconset):
    if os.path.isdir(os.path.join(gajim.DATA_DIR, 'activities', iconset)):
        return os.path.join(gajim.DATA_DIR, 'activities', iconset)
    elif os.path.isdir(os.path.join(gajim.MY_ACTIVITY_ICONSETS_PATH,
    iconset)):
        return os.path.join(gajim.MY_ACTIVITY_ICONSETS_PATH, iconset)
js's avatar
js committed

    if os.path.isdir(os.path.join(gajim.DATA_DIR, 'iconsets', 'transports',
    transport)):
        return os.path.join(gajim.DATA_DIR, 'iconsets', 'transports', transport)
    elif os.path.isdir(os.path.join(gajim.MY_ICONSETS_PATH, 'transports',
    transport)):
        return os.path.join(gajim.MY_ICONSETS_PATH, 'transports', transport)
    # No transport folder found, use default jabber one
    return get_iconset_path(gajim.config.get('iconset'))
steve-e's avatar
steve-e committed

def prepare_and_validate_gpg_keyID(account, jid, keyID):
    """
    Return an eight char long keyID that can be used with for GPG encryption
    with this contact

    If the given keyID is None, return UNKNOWN; if the key does not match the
    assigned key XXXXXXXXMISMATCH is returned. If the key is trusted and not yet
    assigned, assign it.
    """
    if gajim.connections[account].USE_GPG:
        if keyID and len(keyID) == 16:
            keyID = keyID[8:]

        attached_keys = gajim.config.get_per('accounts', account,
                'attached_gpg_keys').split()

        if jid in attached_keys and keyID:
            attachedkeyID = attached_keys[attached_keys.index(jid) + 1]
            if attachedkeyID != keyID:
                # Get signing subkeys for the attached key
                subkeys = []
                for key in gajim.connections[account].gpg.list_keys():
                    if key['keyid'][8:] == attachedkeyID:
                        subkeys = [subkey[0][8:] for subkey in key['subkeys'] \
                            if subkey[1] == 's']
                        break

                if keyID not in subkeys:
                    # Mismatch! Another gpg key was expected
                    keyID += 'MISMATCH'
        elif jid in attached_keys:
            # An unsigned presence, just use the assigned key
            keyID = attached_keys[attached_keys.index(jid) + 1]
        elif keyID:
            public_keys = gajim.connections[account].ask_gpg_keys()
            # Assign the corresponding key, if we have it in our keyring
            if keyID in public_keys:
                for u in gajim.contacts.get_contacts(account, jid):
                    u.keyID = keyID
Dicson's avatar
Dicson committed
                keys_str = gajim.config.get_per('accounts', account,
                    'attached_gpg_keys')
                keys_str += jid + ' ' + keyID + ' '
Dicson's avatar
Dicson committed
                gajim.config.set_per('accounts', account, 'attached_gpg_keys',
                    keys_str)
        elif keyID is None:
            keyID = 'UNKNOWN'
    return keyID
steve-e's avatar
steve-e committed

    import xmpp
    if account:
        accounts = [account]
    else:
        accounts = [a for a in gajim.connections]
    for a in accounts:
        gajim.gajim_optional_features[a] = []
        if gajim.config.get_per('accounts', a, 'subscribe_mood'):
            gajim.gajim_optional_features[a].append(xmpp.NS_MOOD + '+notify')
        if gajim.config.get_per('accounts', a, 'subscribe_activity'):
            gajim.gajim_optional_features[a].append(xmpp.NS_ACTIVITY + '+notify')
        if gajim.config.get_per('accounts', a, 'publish_tune'):
            gajim.gajim_optional_features[a].append(xmpp.NS_TUNE)
        if gajim.config.get_per('accounts', a, 'publish_location'):
            gajim.gajim_optional_features[a].append(xmpp.NS_LOCATION)
        if gajim.config.get_per('accounts', a, 'subscribe_tune'):
            gajim.gajim_optional_features[a].append(xmpp.NS_TUNE + '+notify')
        if gajim.config.get_per('accounts', a, 'subscribe_nick'):
            gajim.gajim_optional_features[a].append(xmpp.NS_NICK + '+notify')
        if gajim.config.get_per('accounts', a, 'subscribe_location'):
            gajim.gajim_optional_features[a].append(xmpp.NS_LOCATION + '+notify')
        if gajim.config.get('outgoing_chat_state_notifactions') != 'disabled':
            gajim.gajim_optional_features[a].append(xmpp.NS_CHATSTATES)
        if not gajim.config.get('ignore_incoming_xhtml'):
            gajim.gajim_optional_features[a].append(xmpp.NS_XHTML_IM)
        if gajim.HAVE_PYCRYPTO \
        and gajim.config.get_per('accounts', a, 'enable_esessions'):
            gajim.gajim_optional_features[a].append(xmpp.NS_ESESSION)
        if gajim.config.get_per('accounts', a, 'answer_receipts'):
            gajim.gajim_optional_features[a].append(xmpp.NS_RECEIPTS)
        if gajim.HAVE_FARSIGHT:
            gajim.gajim_optional_features[a].append(xmpp.NS_JINGLE)
            gajim.gajim_optional_features[a].append(xmpp.NS_JINGLE_RTP)
            gajim.gajim_optional_features[a].append(xmpp.NS_JINGLE_RTP_AUDIO)
            gajim.gajim_optional_features[a].append(xmpp.NS_JINGLE_RTP_VIDEO)
            gajim.gajim_optional_features[a].append(xmpp.NS_JINGLE_ICE_UDP)
        gajim.caps_hash[a] = caps_cache.compute_caps_hash([gajim.gajim_identity],
                gajim.gajim_common_features + gajim.gajim_optional_features[a])
        # re-send presence with new hash
        connected = gajim.connections[a].connected
        if connected > 1 and gajim.SHOW_LIST[connected] != 'invisible':
            gajim.connections[a].change_status(gajim.SHOW_LIST[connected],
                    gajim.connections[a].status)
    return ((jid in gajim.connections[account].blocked_contacts) or \
            gajim.connections[account].blocked_all)
    return ((group in gajim.connections[account].blocked_groups) or \
            gajim.connections[account].blocked_all)
def get_subscription_request_msg(account=None):
    s = gajim.config.get_per('accounts', account, 'subscription_request_msg')
    if s:
        return s
    s = _('I would like to add you to my contact list.')
    if account:
        s = _('Hello, I am $name.') + ' ' + s
        our_jid = gajim.get_jid_from_account(account)
        vcard = gajim.connections[account].get_cached_vcard(our_jid)
        name = ''
        if vcard:
            if 'N' in vcard:
                if 'GIVEN' in vcard['N'] and 'FAMILY' in vcard['N']:
                    name = vcard['N']['GIVEN'] + ' ' + vcard['N']['FAMILY']
            if not name and 'FN' in vcard:
                name = vcard['FN']
        nick = gajim.nicks[account]
        if name and nick:
            name += ' (%s)' % nick
        elif nick:
            name = nick
        s = Template(s).safe_substitute({'name': name})

def replace_dataform_media(form, stanza):
    import xmpp
    found = False
    for field in form.getTags('field'):
        for media in field.getTags('media'):
            for uri in media.getTags('uri'):
                uri_data = uri.getData()
                if uri_data.startswith('cid:'):
                    uri_data = uri_data[4:]
                    for data in stanza.getTags('data', namespace=xmpp.NS_BOB):
                        if data.getAttr('cid') == uri_data:
                            uri.setData(data.getData())
                            found = True