diff --git a/exporter.py b/exporter.py new file mode 100644 index 0000000..d6f9e85 --- /dev/null +++ b/exporter.py @@ -0,0 +1,21 @@ +import os +import sys +import firefly.budgets + +from flask import Flask + + +if 'FIREFLY_PERSONAL_ACCESS_TOKEN' not in os.environ: + print("Please set $FIREFLY_PERSONAL_ACCESS_TOKEN in environment") + sys.exit(1) +if 'FIREFLY_API_HOST' not in os.environ: + print("Please set $FIREFLY_API_HOST in environment") + sys.exit(1) + + +app = Flask(__name__) + + +@app.route('/metrics') +def metric(): + return firefly.budgets.get_budget_metrics() diff --git a/firefly/__init__.py b/firefly/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/firefly/budgets.py b/firefly/budgets.py new file mode 100644 index 0000000..c58fa4a --- /dev/null +++ b/firefly/budgets.py @@ -0,0 +1,97 @@ +"""Expose budget metrics.""" +import os +import calendar +import datetime + +import requests +import dateutil.parser + + +header = {"Authorization": "Bearer " + os.environ.get('FIREFLY_PERSONAL_ACCESS_TOKEN')} +host = os.environ.get('FIREFLY_API_HOST') + + +def _get_budgets(): + budgets_json = requests.get( + host + "/api/v1/budgets", headers=header + ).json() + budgets = budgets_json.get('data') + while "next" in budgets_json.get('links'): + budgets_json = requests.get( + budgets_json.get('links').get('next'), headers=header + ).json() + budgets.extend(budgets_json.get('data')) + return budgets + + +def _get_current_limit(budget_id): + budgets_json = requests.get( + host + "/api/v1/budgets/{}/limits".format(budget_id), headers=header + ).json() + budgets = budgets_json.get('data') + while "next" in budgets_json.get('links'): + budget_json = requests.get( + budgets_json.get('links').get('next'), headers=header + ).json() + budgets.extend(budget_json.get('data')) + + current_budgets = [] + today = datetime.datetime.today() + for budget in budgets: + if today > dateutil.parser.parse(budget.get('attributes').get('start')) and today < dateutil.parser.parse(budget.get('attributes').get('end')): + current_budgets.append(budget) + return current_budgets[0] + + +def _get_current_transactions(budget_id): + limit_id = _get_current_limit(budget_id).get('id') + transactions_json = requests.get( + host + "/api/v1/budgets/limits/{}/transactions".format( + limit_id + ), headers=header + ).json() + transactions = transactions_json.get('data') + while 'next' in transactions_json: + transactions_json = requests.get( + transactions_json.get('links').get('next'), headers=header + ).json() + transactions.extend(transactions_json.get('data')) + return transactions + + +def _get_current_spent_amount(budget_id): + transactions = _get_current_transactions(budget_id) + spent_amount = 0.0 + for transaction in transactions: + for detail in transaction.get('attributes').get('transactions'): + if detail.get('type') == "withdrawal": + spent_amount += float(detail.get('amount')) + else: + print(detail) + return spent_amount + + + +def get_budget_metrics(): + out = "" + for budget in _get_budgets(): + budget_id = budget.get('id') + budget_name = budget.get('attributes').get('name') + budget_limit = _get_current_limit(budget_id).get('attributes').get('amount') + budget_spent = str(_get_current_spent_amount(budget.get('id'))) + + out += 'firefly_budget_limit{{budget_id="{}",budget_name="{}",year="{}",month="{}"}} {}\n'.format( + budget_id, + budget_name, + datetime.datetime.today().year, + datetime.datetime.today().month, + budget_limit, + ) + out += 'firefly_budget_spent{{budget_id="{}",budget_name="{}",year="{}",month="{}"}} {}\n'.format( + budget_id, + budget_name, + datetime.datetime.today().year, + datetime.datetime.today().month, + budget_spent, + ) + return out