<commit_before># coding: utf-8
from __future__ import print_function
from __future__ import unicode_literals

import re
from collections import defaultdict, namedtuple
import operator
import sys
import urllib

from slacker import Slacker
from slack_token import slack_token
from aliases import DEBT_BOT_ALIASES

from transaction import Transaction, TransactionParseError
slack = Slacker(slack_token)

DEBT_CHANNEL_ID = 'C02CWS8H0'


def help_message():
    return """
    Welcome to #debt! I respond to the following commands:
    help: show this menu
    status: show your debtors and creditors
    transactions: show all of your transactions

    new transactions must be in the following format:
    (*user1*) (*operator*) *user2* (*value*) (*notes*), where:
    *user1 and *user2* are names, prefixed with an at-sign;
    *operator* is one of -> or <-;
    *value* is a numerical value;
    *notes* is a field for entering additional text.
    """


def list_channels():
    response = slack.channels.list()
    channels = [{'id': c['id'], 'name': c['name']}
                for c in response.body['channels']]
    print(channels)


def users():
    response = slack.users.list()
    return {m['id']: m['name'] for m in response.body['members']}


def get_channel_history(channel_id):
    response = slack.channels.history(channel=channel_id, count=1000)
    results = [m for m in response.body['messages'] if m.get('text')]

    while response.body['has_more']:
        oldest = min(m.get('ts') for m in response.body['messages'] if m.get('ts'))
        response = slack.channels.history(channel=channel_id, count=1000, latest=oldest)
        results.extend([m for m in response.body['messages'] if m.get('text')])
    return results


def transactions(user_id):
    messages = get_channel_history(DEBT_CHANNEL_ID)
    messages = [m for m in messages if re.search(user_id, m.get('text', ''))]
    return messages


def printable_transactions(user_id):
    def stringify_transaction(t):
        try:
            t = Transaction(m.get('text'))
            if t.parsed:
                return m.get('text')
            else:
                return 'SKIPPED ' + m.get('text')
        except TransactionParseError as err:
            return '❌FAILED! {}\n error ({})'.format(
                m.get('text'), err)

    messages = transactions(user_id)
    return [stringify_transaction(urllib.unquote(m.get('text'))) for m in messages]


def status_for_user(user_id, show_unparsed=False):
    user_list = users()
    balances = defaultdict(float)
    unparsed = list()
    errors = list()
    messages = transactions(user_id)
    for m in messages:
        try:
            transaction = Transaction(m.get('text'))
            if transaction.parsed:
                value, party = transaction.obligation_to_user(user_id)
                balances[party] += value
            else:
                unparsed.append(m.get('text'))
        except Exception as err:
            errors.append((err, m))
            # return "exception %s handling message %s" % (err, m)

    response = response_for_balances(balances, user_list)
    if show_unparsed and len(unparsed):
        response += "\n" + \
            "\n".join(["unabled to parse message: %s" % m for m in unparsed]) + "\n" + \
            "\n".join(["error %s in message %s" % (e, m) for e, m in errors])

    total_value = sum(b for b in balances.values())
    decorator = decoration_for_balance(total_value)
    preamble = "%s status for %s %s\n" % (
        decorator, user_name_for_id(user_id, user_list), decorator)
    return preamble + response


def response_for_balances(balances, user_list):
    responses = list()<commit_msg>fixed ominous bug<commit_after># coding: utf-8
from __future__ import print_function
from __future__ import unicode_literals

import re
from collections import defaultdict, namedtuple
import operator
import sys
import urllib

from slacker import Slacker
from slack_token import slack_token
from aliases import DEBT_BOT_ALIASES

from transaction import Transaction, TransactionParseError
slack = Slacker(slack_token)

DEBT_CHANNEL_ID = 'C02CWS8H0'


def help_message():
    return """
    Welcome to #debt! I respond to the following commands:
    help: show this menu
    status: show your debtors and creditors
    transactions: show all of your transactions

    new transactions must be in the following format:
    (*user1*) (*operator*) *user2* (*value*) (*notes*), where:
    *user1 and *user2* are names, prefixed with an at-sign;
    *operator* is one of -> or <-;
    *value* is a numerical value;
    *notes* is a field for entering additional text.
    """


def list_channels():
    response = slack.channels.list()
    channels = [{'id': c['id'], 'name': c['name']}
                for c in response.body['channels']]
    print(channels)


def users():
    response = slack.users.list()
    return {m['id']: m['name'] for m in response.body['members']}


def get_channel_history(channel_id):
    response = slack.channels.history(channel=channel_id, count=1000)
    results = [m for m in response.body['messages'] if m.get('text')]

    while response.body['has_more']:
        oldest = min(m.get('ts') for m in response.body['messages'] if m.get('ts'))
        response = slack.channels.history(channel=channel_id, count=1000, latest=oldest)
        results.extend([m for m in response.body['messages'] if m.get('text')])
    return results


def transactions(user_id):
    messages = get_channel_history(DEBT_CHANNEL_ID)
    messages = [m for m in messages if re.search(user_id, m.get('text', ''))]
    return messages


def printable_transactions(user_id):
    def stringify_transaction(t):
        try:
            t = Transaction(m.get('text'))
            if t.parsed:
                return m.get('text')
            else:
                return 'SKIPPED ' + m.get('text')
        except TransactionParseError as err:
            return '❌FAILED! {}\n error ({})'.format(
                m.get('text'), err)

    messages = transactions(user_id)
    return [stringify_transaction(urllib.unquote(m.get('text'))) for m in messages]


def status_for_user(user_id, show_unparsed=False):
    user_list = users()
    balances = defaultdict(float)
    unparsed = list()
    errors = list()
    messages = transactions(user_id)
    for m in messages:
        try:
            transaction = Transaction(m.get('text'))
            if transaction.parsed:
                value, party = transaction.obligation_to_user(user_id)
                balances[party] += value
            else:
                unparsed.append(m.get('text'))
        except Exception as err:
            errors.append((err, m))
            # return "exception %s handling message %s" % (err, m)

    response = response_for_balances(balances, user_list, user_id)
    if show_unparsed and len(unparsed):
        response += "\n" + \
            "\n".join(["unabled to parse message: %s" % m for m in unparsed]) + "\n" + \
            "\n".join(["error %s in message %s" % (e, m) for e, m in errors])

    total_value = sum(b for b in balances.values())
    decorator = decoration_for_balance(total_value)
    preamble = "%s status for %s %s\n" % (
        decorator, user_name_for_id(user_id, user_list), decorator)
    return preamble + response


def response_for_balances(balances, user_list, user_id):
    responses = list()
{'fraction_non_alphanumeric': 0.11844240129799892, 'fraction_numerical': 0.004597079502433748, 'mean_word_length': 3.0005408328826393, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3179207', 'n_tokens_mistral': 2283, 'n_tokens_neox': 2225, 'n_words': 653}