Exemple #1
0
def login_check_menu(bank_info):
    while 1:
        username = ''
        while not username:
            username = prompt('username> ')

        password = ''
        while not password:
            password = getpass.getpass('password> ')

        i = Institution(id=bank_info['fid'],
                        org=bank_info['org'],
                        url=bank_info['url'],
                        broker_id=bank_info['brokerid'],
                        description=bank_info['name'],
                        username=username,
                        password=password)
        try:
            i.authenticate()
        except Exception, e:
            print "authentication failed: %s" % e
            continue

        accounts = i.accounts()
        for a in accounts:
            GlobalConfig.add_account(a)
        GlobalConfig.save()
        return 1
Exemple #2
0
def login_check_menu(bank_info):
    while 1:
        username = ''
        while not username:
            username = prompt('username> ')

        password = ''
        while not password:
            password = getpass.getpass('password> ')

        i = Institution(
            id=bank_info['fid'],
            org=bank_info['org'],
            url=bank_info['url'],
            broker_id=bank_info['brokerid'],
            description=bank_info['name'],
            username=username,
            password=password
        )
        try:
            i.authenticate()
        except Exception as e:
            print("authentication failed: %s" % e)
            raise
            continue

        accounts = i.accounts()
        for a in accounts:
            GlobalConfig.add_account(a)
        GlobalConfig.save()
        return 1
Exemple #3
0
def login_check_menu(bank_info, args):
    print('------')
    print('Notice')
    print('------')
    print('You are about to test to make sure your username and password')
    print('are correct.  This means you will be sending it to the URL below.')
    print('If the URL does not appear to belong to your bank then you should')
    print('exit this program by hitting CTRL-C.')
    print('  bank name: %s' % (bank_info['name']))
    print('  bank url:  %s' % (bank_info['url']))
    print('------')
    while 1:
        username = ''
        while not username:
            username = prompt('username> ')

        password = ''
        prompt_text = 'password> '
        if os.name == 'nt' and sys.version_info < (3, 0):
            prompt_text = prompt_text.encode('utf8')
        while not password:
            password = getpass.getpass(prompt=prompt_text)

        i = Institution(id=bank_info['fid'],
                        org=bank_info['org'],
                        url=bank_info['url'],
                        broker_id=bank_info['brokerid'],
                        description=bank_info['name'],
                        username=username,
                        password=password,
                        client_args=client_args_for_bank(
                            bank_info, args.ofx_version))
        try:
            i.authenticate()
        except Exception as e:
            print("authentication failed: %s" % e)
            continue

        print('Sleeping')
        time.sleep(2)
        accounts = i.accounts()
        for a in accounts:
            GlobalConfig.add_account(a)
        GlobalConfig.save()
        return 1
Exemple #4
0
def login_check_menu(bank_info, args):
    print('------')
    print('Notice')
    print('------')
    print('You are about to test to make sure your username and password')
    print('are correct.  This means you will be sending it to the URL below.')
    print('If the URL does not appear to belong to your bank then you should')
    print('exit this program by hitting CTRL-C.')
    print('  bank name: %s' % (bank_info['name']))
    print('  bank url:  %s' % (bank_info['url']))
    print('------')
    while 1:
        username = ''
        while not username:
            username = prompt('username> ')

        password = ''
        prompt_text = 'password> '
        if os.name == 'nt' and sys.version_info < (3, 0):
            prompt_text = prompt_text.encode('utf8')
        while not password:
            password = getpass.getpass(prompt=prompt_text)

        i = Institution(
            id=bank_info['fid'],
            org=bank_info['org'],
            url=bank_info['url'],
            broker_id=bank_info['brokerid'],
            description=bank_info['name'],
            username=username,
            password=password,
            client_args=client_args_for_bank(bank_info, args.ofx_version)
        )
        try:
            i.authenticate()
        except Exception as e:
            print("authentication failed: %s" % e)
            continue

        accounts = i.accounts()
        for a in accounts:
            GlobalConfig.add_account(a)
        GlobalConfig.save()
        return 1
Exemple #5
0
def login_check_menu(bank_info, args):
    print("------")
    print("Notice")
    print("------")
    print("You are about to test to make sure your username and password")
    print("are correct.  This means you will be sending it to the URL below.")
    print("If the URL does not appear to belong to your bank then you should")
    print("exit this program by hitting CTRL-C.")
    print("  bank name: %s" % (bank_info["name"]))
    print("  bank url:  %s" % (bank_info["url"]))
    print("------")
    while 1:
        username = ""
        while not username:
            username = prompt("username> ")

        password = ""
        prompt_text = "password> "
        if os.name == "nt" and sys.version_info < (3, 0):
            prompt_text = prompt_text.encode("utf8")
        while not password:
            password = getpass.getpass(prompt=prompt_text)

        i = Institution(
            id=bank_info["fid"],
            org=bank_info["org"],
            url=bank_info["url"],
            broker_id=bank_info["brokerid"],
            description=bank_info["name"],
            username=username,
            password=password,
            client_args={ofx_version: args.ofx_version},
        )
        try:
            i.authenticate()
        except Exception as e:
            print("authentication failed: %s" % e)
            continue

        accounts = i.accounts()
        for a in accounts:
            GlobalConfig.add_account(a)
        GlobalConfig.save()
        return 1
Exemple #6
0
def login_check_menu(bank_info):
    print('------')
    print('Notice')
    print('------')
    print('You are about to test to make sure your username and password')
    print('are correct.  This means you will be sending it to the URL below.')
    print('If the URL does not appear to belong to your bank then you should')
    print('exit this program by hitting CTRL-C.')
    print('  bank name: %s' % (bank_info['name']))
    print('  bank url:  %s' % (bank_info['url']))
    print('------')
    while 1:
        username = ''
        while not username:
            username = prompt('username> ')

        password = ''
        while not password:
            password = getpass.getpass('password> ')

        i = Institution(id=bank_info['fid'],
                        org=bank_info['org'],
                        url=bank_info['url'],
                        broker_id=bank_info['brokerid'],
                        description=bank_info['name'],
                        username=username,
                        password=password)
        try:
            i.authenticate()
        except Exception as e:
            print("authentication failed: %s" % e)
            continue

        accounts = i.accounts()
        for a in accounts:
            GlobalConfig.add_account(a)
        GlobalConfig.save()
        return 1
Exemple #7
0
    def deserialize(raw):
        """Instantiate :py:class:`ofxclient.Account` subclass from dictionary

        :param raw: serilized Account
        :param type: dict as  given by :py:meth:`~ofxclient.Account.serialize`
        :rtype: subclass of :py:class:`ofxclient.Account`
        """
        from ofxclient.institution import Institution
        institution = Institution.deserialize(raw['institution'])

        del raw['institution']
        del raw['local_id']

        if 'broker_id' in raw:
            a = BrokerageAccount(institution=institution, **raw)
        elif 'routing_number' in raw:
            a = BankAccount(institution=institution, **raw)
        else:
            a = CreditCardAccount(institution=institution, **raw)
        return a
Exemple #8
0
    def deserialize(raw):
        """Instantiate :py:class:`ofxclient.Account` subclass from dictionary

        :param raw: serilized Account
        :param type: dict as  given by :py:meth:`~ofxclient.Account.serialize`
        :rtype: subclass of :py:class:`ofxclient.Account`
        """
        from ofxclient.institution import Institution
        institution = Institution.deserialize(raw['institution'])

        del raw['institution']
        del raw['local_id']

        if 'broker_id' in raw:
            a = BrokerageAccount(institution=institution, **raw)
        elif 'routing_number' in raw:
            a = BankAccount(institution=institution, **raw)
        else:
            a = CreditCardAccount(institution=institution, **raw)
        return a
def lambda_func(event, context=None):
    beginf = time.time()
    query = event['body']
    gettimes = []
    cmdtimes = []
    result = {}
    if not event['headers'].has_key('Authorization'):
        result['error'] = "Missing Auth Header"
        return result
    token_header_parts = event['headers']['Authorization'].split(" ")
    if len(token_header_parts) != 2 or token_header_parts[0] != "Bearer":
        result['error'] = "Malformed Auth Header"
        return result
    token_string = token_header_parts[1]

    headers = jwt.get_unverified_headers(token_string)

    kid = headers['kid']
    key_index = -1
    for i in range(len(JWT_KEYS)):
        if kid == JWT_KEYS[i]['kid']:
            key_index = i
            break
    if key_index == -1:
        result['error'] = 'Public key not found'
        return result

    try:
        decode = jwt.decode(token_string,
                            JWT_KEYS[key_index],
                            algorithms=['RS256'],
                            issuer=JWT_ISSUER)
    except:
        result['error'] = "Not Authorized"
        return result

    if query['query'] == 'getfile':
        filename = os.path.split(query['filename'])[-1]
        if filename.startswith('online'):
            begin = time.time()
            result['contents'] = get_file_from_s3(filename, query["creds"])
            end = time.time()
            gettimes.append(end - begin)
        else:
            result['error'] = "Filenames must begin with online"
    elif query['query'] == 'savefile':
        filename = os.path.split(query['filename'])[-1]
        if filename.startswith('online'):
            try:
                save_file_to_s3(filename, query['contents'], query["creds"])
                result['success'] = True
            except:
                result['success'] = False
        else:
            result['error'] = "Filenames must begin with online"
    elif query['query'] == 'report':
        command = None
        if query.has_key('name'):
            reportType = None
            historical = "auto"
            if query.has_key('historical'):
                historical = query['historical']

            if query['name'] == "accounts":
                command = ["hledger", "-I", "-f", "-", "accounts"]
                reportType = "accounts"
            elif query['name'] == "budget":
                command = ["hledger", "-I", "-f", "-", "accounts"]
                reportType = "budget"
            else:
                if query['name'] == "balance":
                    command = [
                        "hledger", "-f", "-", "balance", "--tree", "-O", "csv"
                    ]
                    reportType = "balance"
                    if historical == "includehistorical":
                        command.append('-H')
                        historical = None
                elif query['name'] == "register" or query[
                        'name'] == "budgetregister" or query[
                            'name'] == "combinedregister":
                    if query['name'] == "combinedregister":
                        command = [
                            "hledger", "-I", "-f", "-", "register", "-O", "csv"
                        ]
                    else:
                        command = [
                            "hledger", "-f", "-", "register", "-O", "csv"
                        ]
                    if historical == "auto" or historical == "includehistorical":
                        command.append('-H')
                        historical = None
                    reportType = query['name']
                if command and query.has_key('time'):
                    command.append('-p')
                    command.append(query['time'])
                if command and query.has_key('timeperiod'):
                    if query['timeperiod'] in [
                            'monthly', 'weekly', 'yearly', 'quarterly', 'daily'
                    ]:
                        command.append('--' + query['timeperiod'])
                if command and query.has_key('accounts'):
                    parts = query['accounts'].split('_')
                    if len(parts) > 1 and parts[1]:
                        command.append('^' + parts[1])
                        if historical == "auto" and (
                            (parts[1].startswith('Assets:')
                             or parts[1].startswith('Liabailities:'))):
                            command.append('-H')
                    else:
                        if parts[0] == "expenses":
                            command.append('^Expenses:')
                        elif parts[0] == "income":
                            command.append('^Income:')
                        elif parts[0] == "incomeexpenses":
                            command.append('^Income:|^Expenses:')
                        elif parts[0] == "assets":
                            command.append('^Assets:')
                            if historical == "auto":
                                command.append('-H')
                        elif parts[0] == "assetssummary":
                            command.append('^Assets:')
                            command.append('--depth')
                            command.append('2')
                            if historical == "auto":
                                command.append('-H')
                        elif parts[0] == "liabilities":
                            command.append('^Liabilities:')
                            if historical == "auto":
                                command.append('-H')
                        elif parts[0] == "assetsliabilities":
                            command.append('^Assets:|^Liabilities:')
                            if historical == "auto":
                                command.append('-H')
        if command:
            if reportType == "budget" or reportType == "accounts" or reportType == "combinedregister":
                begin = time.time()
                defaultledger = get_file_from_s3("online.ledger",
                                                 query["creds"])
                end = time.time()
                gettimes.append(end - begin)
                begin = time.time()
                budgetledger = get_file_from_s3("onlinebudget.ledger",
                                                query["creds"])
                end = time.time()
                gettimes.append(end - begin)
                begin = time.time()
                output, errors = subprocess.Popen(
                    command,
                    stdin=subprocess.PIPE,
                    stdout=subprocess.PIPE,
                    stderr=subprocess.PIPE,
                    env=launch_env).communicate(defaultledger + os.linesep +
                                                budgetledger)
                end = time.time()
                cmdtimes.append(end - begin)
            elif reportType == "budgetregister":
                begin = time.time()
                budgetledger = get_file_from_s3("onlinebudget.ledger",
                                                query["creds"])
                end = time.time()
                gettimes.append(end - begin)
                begin = time.time()
                output, errors = subprocess.Popen(
                    command,
                    stdin=subprocess.PIPE,
                    stdout=subprocess.PIPE,
                    stderr=subprocess.PIPE,
                    env=launch_env).communicate(budgetledger)
                end = time.time()
                cmdtimes.append(end - begin)
            else:
                begin = time.time()
                defaultledger = get_file_from_s3("online.ledger",
                                                 query["creds"])
                end = time.time()
                gettimes.append(end - begin)
                begin = time.time()
                output, errors = subprocess.Popen(
                    command,
                    stdin=subprocess.PIPE,
                    stdout=subprocess.PIPE,
                    stderr=subprocess.PIPE,
                    env=launch_env).communicate(defaultledger)
                end = time.time()
                cmdtimes.append(end - begin)
            if errors:
                result["error"] = "Report failed: " + errors
            else:
                try:
                    items = []
                    if reportType == "accounts":
                        result = {"result": output.splitlines()}
                    elif reportType == "budget":
                        allaccounts = output.splitlines()
                        transactionfilter = '^' + '$|^'.join(
                            filter(
                                lambda aname: aname.find("Off-Budget") < 0 and
                                not aname.startswith("Expenses:") and not aname
                                .startswith("Income:") and not aname.
                                startswith("Equity:"), allaccounts)) + '$'
                        # Filter and get rid of asset accounts that are part of the budget
                        allaccounts = filter(
                            lambda aname: aname.find("Off-Budget") >= 0 or
                            not aname.startswith("Assets:"), allaccounts)
                        command = [
                            "hledger", "-I", "-f", "-", "print",
                            transactionfilter
                        ]
                        begin = time.time()
                        filteredledger, errors = subprocess.Popen(
                            command,
                            stdin=subprocess.PIPE,
                            stdout=subprocess.PIPE,
                            stderr=subprocess.PIPE,
                            env=launch_env).communicate(defaultledger)
                        end = time.time()
                        cmdtimes.append(end - begin)
                        # Budget report involves 3 reports with various inputs
                        command = [
                            "hledger", "-I", "-f", "-", "balance", "--tree",
                            "-O", "csv", "-E", "-p",
                            query.get('time', ['thismonth'])
                        ]
                        if query.has_key(
                                'budgetperiod') and query['budgetperiod'] in [
                                    'monthly', 'weekly', 'yearly', 'quarterly',
                                    'daily'
                                ]:
                            command.append('--' + query['budgetperiod'])
                        else:
                            command.append('--monthly')
                        begin = time.time()
                        budgetoutput, errors = subprocess.Popen(
                            command,
                            stdin=subprocess.PIPE,
                            stdout=subprocess.PIPE,
                            stderr=subprocess.PIPE,
                            env=launch_env).communicate(budgetledger)
                        end = time.time()
                        cmdtimes.append(end - begin)
                        if errors:
                            result["error"] = "Budget report failed: " + errors
                        else:
                            command = [
                                "hledger", "-f", "-", "balance", "--tree",
                                "-O", "csv", "-E", "-p",
                                query.get('time', ['thismonth'])
                            ]
                            if query.has_key(
                                    'timeperiod') and query['timeperiod'] in [
                                        'monthly', 'weekly', 'yearly',
                                        'quarterly', 'daily'
                                    ]:
                                command.append('--' + query['timeperiod'])
                            else:
                                command.append('--monthly')
                            begin = time.time()
                            spendingoutput, errors = subprocess.Popen(
                                command,
                                stdin=subprocess.PIPE,
                                stdout=subprocess.PIPE,
                                stderr=subprocess.PIPE,
                                env=launch_env).communicate(filteredledger)
                            end = time.time()
                            cmdtimes.append(end - begin)
                            if errors:
                                result[
                                    "error"] = "Budget spending report failed: " + errors
                            else:
                                command = [
                                    "hledger", "-I", "-f", "-", "balance",
                                    "--tree", "-O", "csv", "-E", "-H", "-p",
                                    query.get('time', ['thismonth'])
                                ]
                                if query.has_key('timeperiod'
                                                 ) and query['timeperiod'] in [
                                                     'monthly', 'weekly',
                                                     'yearly', 'quarterly',
                                                     'daily'
                                                 ]:
                                    command.append('--' + query['timeperiod'])
                                else:
                                    command.append('--monthly')

                                begin = time.time()
                                balanceoutput, errors = subprocess.Popen(
                                    command,
                                    stdin=subprocess.PIPE,
                                    stdout=subprocess.PIPE,
                                    stderr=subprocess.PIPE,
                                    env=launch_env).communicate(
                                        filteredledger + os.linesep +
                                        budgetledger)
                                end = time.time()
                                cmdtimes.append(end - begin)
                                if errors:
                                    result[
                                        "error"] = "Budget balance report failed: " + errors
                                else:
                                    budgetitems = {}
                                    spendingitems = {}
                                    balanceitems = {}
                                    reader = csv.DictReader(
                                        StringIO.StringIO(budgetoutput))
                                    budgetcolumns = []
                                    reportcolumns = []
                                    columns = []
                                    foundbudgetkeys = False
                                    foundspendingkeys = False
                                    foundbalancekeys = False
                                    for row in reader:
                                        if row['Account'] != "total":
                                            if not foundbudgetkeys:
                                                for col in row.keys():
                                                    fixedcol = fix_column_name(
                                                        col)
                                                    if fixedcol[0].isdigit(
                                                    ) and fixedcol not in budgetcolumns:
                                                        budgetcolumns.append(
                                                            fixedcol)
                                                        columns.append(
                                                            (fixedcol, 0,
                                                             "Budget " +
                                                             fixedcol, col))
                                                foundbudgetkeys = True
                                            budgetitems[row['Account']] = row
                                    reader = csv.DictReader(
                                        StringIO.StringIO(spendingoutput))
                                    for row in reader:
                                        if row['Account'] != "total":
                                            if not foundspendingkeys:
                                                for col in row.keys():
                                                    fixedcol = fix_column_name(
                                                        col)
                                                    if fixedcol[0].isdigit(
                                                    ) and fixedcol not in reportcolumns:
                                                        reportcolumns.append(
                                                            fixedcol)
                                                        columns.append(
                                                            (fixedcol, 1,
                                                             "Actual " +
                                                             fixedcol, col))
                                                        columns.append(
                                                            (fixedcol, 2,
                                                             "Balance " +
                                                             fixedcol, col))
                                                foundspendingkeys = True
                                            spendingitems[row['Account']] = row
                                    reader = csv.DictReader(
                                        StringIO.StringIO(balanceoutput))
                                    for row in reader:
                                        if row['Account'] != "total":
                                            if not foundbalancekeys:
                                                for col in row.keys():
                                                    fixedcol = fix_column_name(
                                                        col)
                                                    if col[0].isdigit(
                                                    ) and fixedcol not in reportcolumns:
                                                        reportcolumns.append(
                                                            fixedcol)
                                                        columns.append(
                                                            (fixedcol, 1,
                                                             "Actual " +
                                                             fixedcol, col))
                                                        columns.append(
                                                            (fixedcol, 2,
                                                             "Balance " +
                                                             fixedcol, col))
                                                foundbalancekeys = True
                                            balanceitems[row['Account']] = row
                                    # Now assemble header row
                                    header = ['account']
                                    columns.sort()
                                    firstbudget = -1
                                    firstbudgetidx = 0
                                    for col, order, colname, lookupcol in columns:
                                        if firstbudget < 0:
                                            if order == 0:
                                                firstbudget = firstbudgetidx
                                            else:
                                                firstbudgetidx += 1
                                                continue
                                        header.append(colname)
                                    if firstbudgetidx >= 0:
                                        columns = columns[firstbudgetidx:]
                                    # Now assemble report rows
                                    totals = {'account': 'Total'}
                                    for acct in allaccounts:
                                        if budgetitems.has_key(
                                                acct) or spendingitems.has_key(
                                                    acct
                                                ) or balanceitems.has_key(
                                                    acct):
                                            row = {'account': acct}
                                            for col, order, colname, lookupcol in columns:
                                                if order == 0:  # Budget column
                                                    if budgetitems.has_key(
                                                            acct
                                                    ) and budgetitems[
                                                            acct].has_key(
                                                                lookupcol):
                                                        row[colname] = negateamount(
                                                            budgetitems[acct]
                                                            [lookupcol])
                                                    else:
                                                        row[colname] = "0"
                                                elif order == 1:  # Actual column
                                                    if spendingitems.has_key(
                                                            acct
                                                    ) and spendingitems[
                                                            acct].has_key(
                                                                lookupcol):
                                                        row[colname] = negateamount(
                                                            spendingitems[acct]
                                                            [lookupcol])
                                                    else:
                                                        row[colname] = "0"
                                                elif order == 2:  # Balance column
                                                    if balanceitems.has_key(
                                                            acct
                                                    ) and balanceitems[
                                                            acct].has_key(
                                                                lookupcol):
                                                        row[colname] = negateamount(
                                                            balanceitems[acct]
                                                            [lookupcol])
                                                    else:
                                                        row[colname] = "0"
                                                aggregate_total(
                                                    totals, colname,
                                                    row[colname])
                                            keeprow = False
                                            if row['account'].startswith(
                                                    'Expenses:'
                                            ) or row['account'].startswith(
                                                    'Income:'
                                            ) or row['account'].startswith(
                                                    'Assets:'):
                                                keeprow = True
                                            for colname in row.keys():
                                                if colname != 'account' and row[
                                                        colname] != '0':
                                                    keeprow = True
                                            if keeprow:
                                                items.append(row)
                                    items.append(totals)
                                    result["headers"] = header
                                    result["result"] = items

                    else:
                        reader = csv.DictReader(StringIO.StringIO(output))
                        for row in reader:
                            if reportType == "budgetregister" or reportType == "combinedregister":
                                for k in row.keys():
                                    if k != "txnidx" and k != "date" and k != "description" and k != "account":
                                        row[k] = negateamount(row[k])
                            items.append(row)
                        result["headers"] = reader.fieldnames
                        result["result"] = items
                except:
                    result[
                        "error"] = "Report failed to produce readable results"
        else:
            result["error"] = "Bad report parameters"
    elif query['query'] == 'validate':
        options = ["-I"]
        if query.has_key('assertions') and query['assertions']:
            options = []
        command = ["hledger", "-f", "-"] + options + ["print"]
        ledger = query['contents']
        begin = time.time()
        validateoutput, errors = subprocess.Popen(
            command,
            stdin=subprocess.PIPE,
            stdout=subprocess.PIPE,
            stderr=subprocess.PIPE,
            env=launch_env).communicate(ledger)
        end = time.time()
        cmdtimes.append(end - begin)
        if validateoutput:
            result["output"] = validateoutput
        if errors:
            result["error"] = errors

    elif query['query'] == 'parseofx':
        ofxdata = query['contents']
        parser = OfxParser.parse(StringIO.StringIO(ofxdata))
        convdate = lambda d: ("%0.4d/%0.2d/%0.2d" % (d.year, d.month, d.day)
                              ) if d is not None and hasattr(d, 'year'
                                                             ) else None
        strifnotnone = lambda s: str(s) if s is not None else s

        result["ofxaccounts"] = [{
            "fid":
            getattr(account.institution, "fid", None),
            "organization":
            getattr(account.institution, "organization", None),
            "account_id":
            getattr(account, "account_id", None),
            "number":
            getattr(account, "number", None),
            "routing_number":
            getattr(account, "routing_number", None),
            "type":
            getattr(account, "type", None),
            "account_type":
            getattr(account, "account_type", None),
            "statement": {
                "available_balance":
                strifnotnone(
                    getattr(account.statement, "available_balance", None)),
                "available_balance_date":
                convdate(
                    getattr(account.statement, "available_balance_date",
                            None)),
                "balance":
                strifnotnone(getattr(account.statement, "balance", None)),
                "balance_date":
                convdate(getattr(account.statement, "balance_date", None)),
                "start_date":
                convdate(getattr(account.statement, "start_date", None)),
                "end_date":
                convdate(getattr(account.statement, "end_date", None)),
                "currency":
                getattr(account.statement, "currency", None),
                "transactions": [{
                    "amount": strifnotnone(txn.amount),
                    "checknum": getattr(txn, "checknum", None),
                    "date": convdate(getattr(txn, "date", None)),
                    "id": getattr(txn, "id", None),
                    "mcc": getattr(txn, "mcc", None),
                    "memo": getattr(txn, "memo", None),
                    "payee": getattr(txn, "payee", None),
                    "sic": getattr(txn, "sic", None),
                    "type": getattr(txn, "type", None)
                } for txn in account.statement.transactions]
            }
        } for account in parser.accounts]

    elif query['query'] == 'downloadofx':
        try:
            #    config = ConfigParser.ConfigParser()
            #    config.readfp(StringIO.StringIO(query['ofxconfig']))
            #    ofxclient.config.unflatten_dict(dict(config.items(config.sections()[0])))
            #    acct = ofxclient.account.Account.deserialize(ofxclient.config.unflatten_dict(dict(config.items(config.sections()[0]))))
            acct = ofxclient.account.Account.deserialize(query['ofxconfig'])
            dat = acct.download()
            result["contents"] = dat.read()
        except Exception as ex:
            result["error"] = str(ex)

    elif query['query'] == 'searchofxhome':
        try:
            result["result"] = list(OFXHome.search(query['search']))
        except Exception as ex:
            result["error"] = str(ex)

    elif query['query'] == 'getofxaccounts':
        try:
            version = DEFAULT_OFX_VERSION
            if query.has_key('ofx_version'):
                version = int(query['ofx_version'])
            bank_info = OFXHome.lookup(query['ofxhomeid'])
            if bank_info:
                i = Institution(id=bank_info['fid'],
                                org=bank_info['org'],
                                url=bank_info['url'],
                                broker_id=bank_info['brokerid'],
                                description=bank_info['name'],
                                username=query['username'],
                                password=query['password'],
                                client_args=ofxclient.cli.client_args_for_bank(
                                    bank_info, version))
                failed = False
                try:
                    i.authenticate()
                except Exception as ex:
                    failed = True
                    result["error"] = "Authentication failed: " + str(ex)
                if not failed:
                    accts = i.accounts()
                    result["result"] = [acct.serialize() for acct in accts]
            else:
                result["error"] = "Could not find bank"
        except Exception as ex:
            result["error"] = "Failure: " + str(ex)
    else:
        result["error"] = "Bad query"

    endf = time.time()
    result["log"] = {
        "totaltime": (endf - beginf),
        "gettimes": gettimes,
        "cmdtimes": cmdtimes
    }
    return result