mirror of
https://github.com/elisiariocouto/leggen.git
synced 2025-12-13 21:52:40 +00:00
Compare commits
6 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4f2daa7953 | ||
|
|
d8aa1ef90d | ||
|
|
f3ad639a01 | ||
|
|
facf6ac94e | ||
|
|
d8fde49da4 | ||
|
|
460fed3ed0 |
20
CHANGELOG.md
20
CHANGELOG.md
@@ -1,3 +1,23 @@
|
|||||||
|
## 0.2.2 (2024/03/01)
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
- **sync:** Pending dates can be null. ([d8aa1ef9](https://github.com/elisiariocouto/leggen/commit/d8aa1ef90d263771b080194adc9e983b1b3d56fe))
|
||||||
|
|
||||||
|
|
||||||
|
## 0.2.1 (2024/02/29)
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
- Fix compose volumes and dependencies. ([460fed3e](https://github.com/elisiariocouto/leggen/commit/460fed3ed0ca694eab6e80f98392edbe5d5b83fd))
|
||||||
|
- Deduplicate accounts. ([facf6ac9](https://github.com/elisiariocouto/leggen/commit/facf6ac94e533087846fca297520c311a81b6692))
|
||||||
|
|
||||||
|
|
||||||
|
### Documentation
|
||||||
|
|
||||||
|
- Add NocoDB information to README.md. ([d8fde49d](https://github.com/elisiariocouto/leggen/commit/d8fde49da4e34457a7564655dd42bb6f0d427b4b))
|
||||||
|
|
||||||
|
|
||||||
## 0.2.0 (2024/02/27)
|
## 0.2.0 (2024/02/27)
|
||||||
|
|
||||||
### Bug Fixes
|
### Bug Fixes
|
||||||
|
|||||||
@@ -12,8 +12,9 @@ Having your bank data in a database, gives you the power to backup, analyze and
|
|||||||
- Python: for the CLI
|
- Python: for the CLI
|
||||||
- [GoCardless Open Banking API](https://developer.gocardless.com/bank-account-data/overview): for connecting to banks
|
- [GoCardless Open Banking API](https://developer.gocardless.com/bank-account-data/overview): for connecting to banks
|
||||||
- [SQLite](https://www.sqlite.org): for storing transactions, simple and easy to use
|
- [SQLite](https://www.sqlite.org): for storing transactions, simple and easy to use
|
||||||
- [MongoDB](https://www.mongodb.com/docs/): alternative store for transactions, good balance between performance and query capabilities
|
- [NocoDB](https://github.com/nocodb/nocodb): for visualizing and querying transactions, a simple and easy to use interface for SQLite
|
||||||
- [Ofelia](https://github.com/mcuadros/ofelia): for scheduling regular syncs with the database when using Docker
|
- [Ofelia](https://github.com/mcuadros/ofelia): for scheduling regular syncs with the database when using Docker
|
||||||
|
- [MongoDB](https://www.mongodb.com/docs/): alternative store for transactions, good balance between performance and query capabilities
|
||||||
|
|
||||||
## ✨ Features
|
## ✨ Features
|
||||||
- Connect to banks using GoCardless Open Banking API
|
- Connect to banks using GoCardless Open Banking API
|
||||||
|
|||||||
@@ -12,18 +12,19 @@ services:
|
|||||||
# Uncomment the following lines if you use MongoDB
|
# Uncomment the following lines if you use MongoDB
|
||||||
# LEGGEN_MONGO_URI: "mongodb://leggen:changeme@mongo:27017/leggen"
|
# LEGGEN_MONGO_URI: "mongodb://leggen:changeme@mongo:27017/leggen"
|
||||||
volumes:
|
volumes:
|
||||||
- "./leggen:/root"
|
- "./leggen:/root/.config/leggen"
|
||||||
depends_on:
|
- "./db:/app"
|
||||||
- mongo
|
|
||||||
|
|
||||||
nocodb:
|
nocodb:
|
||||||
image: nocodb/nocodb:latest
|
image: nocodb/nocodb:latest
|
||||||
restart: "unless-stopped"
|
restart: "unless-stopped"
|
||||||
volumes:
|
volumes:
|
||||||
- "./nocodb:/usr/app/data/"
|
- "./nocodb:/usr/app/data/"
|
||||||
- "./leggen:/usr/leggen:ro"
|
- "./db:/usr/leggen:ro"
|
||||||
ports:
|
ports:
|
||||||
- "127.0.0.1:8080:8080"
|
- "127.0.0.1:8080:8080"
|
||||||
|
depends_on:
|
||||||
|
- leggen
|
||||||
|
|
||||||
# Recommended: Run `leggen sync` every day.
|
# Recommended: Run `leggen sync` every day.
|
||||||
ofelia:
|
ofelia:
|
||||||
|
|||||||
@@ -13,9 +13,9 @@ def balances(ctx: click.Context):
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
res = get(ctx, "/requisitions/")
|
res = get(ctx, "/requisitions/")
|
||||||
accounts = []
|
accounts = set()
|
||||||
for r in res.get("results", []):
|
for r in res.get("results", []):
|
||||||
accounts += r.get("accounts", [])
|
accounts.update(r.get("accounts", []))
|
||||||
|
|
||||||
all_balances = []
|
all_balances = []
|
||||||
for account in accounts:
|
for account in accounts:
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ def status(ctx: click.Context):
|
|||||||
|
|
||||||
res = get(ctx, "/requisitions/")
|
res = get(ctx, "/requisitions/")
|
||||||
requisitions = []
|
requisitions = []
|
||||||
accounts = []
|
accounts = set()
|
||||||
for r in res["results"]:
|
for r in res["results"]:
|
||||||
requisitions.append(
|
requisitions.append(
|
||||||
{
|
{
|
||||||
@@ -24,7 +24,7 @@ def status(ctx: click.Context):
|
|||||||
"Created at": datefmt(r["created"]),
|
"Created at": datefmt(r["created"]),
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
accounts += r.get("accounts", [])
|
accounts.update(r.get("accounts", []))
|
||||||
info("Banks")
|
info("Banks")
|
||||||
print_table(requisitions)
|
print_table(requisitions)
|
||||||
|
|
||||||
|
|||||||
@@ -21,13 +21,16 @@ def save_transactions(ctx: click.Context, account: str):
|
|||||||
)
|
)
|
||||||
|
|
||||||
for transaction in account_transactions.get("booked", []):
|
for transaction in account_transactions.get("booked", []):
|
||||||
booked_date = datetime.fromisoformat(
|
booked_date = transaction.get("bookingDateTime") or transaction.get(
|
||||||
transaction.get("bookingDateTime", transaction.get("bookingDate"))
|
"bookingDate"
|
||||||
)
|
)
|
||||||
value_date = datetime.fromisoformat(
|
value_date = transaction.get("valueDateTime") or transaction.get("valueDate")
|
||||||
transaction.get("valueDateTime", transaction.get("valueDate"))
|
if booked_date and value_date:
|
||||||
)
|
min_date = min(
|
||||||
min_date = min(booked_date, value_date)
|
datetime.fromisoformat(booked_date), datetime.fromisoformat(value_date)
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
min_date = datetime.fromisoformat(booked_date or value_date)
|
||||||
|
|
||||||
transactionValue = float(
|
transactionValue = float(
|
||||||
transaction.get("transactionAmount", {}).get("amount", 0)
|
transaction.get("transactionAmount", {}).get("amount", 0)
|
||||||
@@ -54,13 +57,16 @@ def save_transactions(ctx: click.Context, account: str):
|
|||||||
transactions.append(t)
|
transactions.append(t)
|
||||||
|
|
||||||
for transaction in account_transactions.get("pending", []):
|
for transaction in account_transactions.get("pending", []):
|
||||||
booked_date = datetime.fromisoformat(
|
booked_date = transaction.get("bookingDateTime") or transaction.get(
|
||||||
transaction.get("bookingDateTime", transaction.get("bookingDate"))
|
"bookingDate"
|
||||||
)
|
)
|
||||||
value_date = datetime.fromisoformat(
|
value_date = transaction.get("valueDateTime") or transaction.get("valueDate")
|
||||||
transaction.get("valueDateTime", transaction.get("valueDate"))
|
if booked_date and value_date:
|
||||||
)
|
min_date = min(
|
||||||
min_date = min(booked_date, value_date)
|
datetime.fromisoformat(booked_date), datetime.fromisoformat(value_date)
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
min_date = datetime.fromisoformat(booked_date or value_date)
|
||||||
|
|
||||||
transactionValue = float(
|
transactionValue = float(
|
||||||
transaction.get("transactionAmount", {}).get("amount", 0)
|
transaction.get("transactionAmount", {}).get("amount", 0)
|
||||||
@@ -104,10 +110,9 @@ def sync(ctx: click.Context):
|
|||||||
"""
|
"""
|
||||||
info("Getting accounts details")
|
info("Getting accounts details")
|
||||||
res = get(ctx, "/requisitions/")
|
res = get(ctx, "/requisitions/")
|
||||||
accounts = []
|
accounts = set()
|
||||||
for r in res.get("results", []):
|
for r in res.get("results", []):
|
||||||
accounts += r.get("accounts", [])
|
accounts.update(r.get("accounts", []))
|
||||||
accounts = list(set(accounts))
|
|
||||||
|
|
||||||
info(f"Syncing transactions for {len(accounts)} accounts")
|
info(f"Syncing transactions for {len(accounts)} accounts")
|
||||||
|
|
||||||
|
|||||||
@@ -41,9 +41,9 @@ def transactions(ctx: click.Context, account: str):
|
|||||||
print_transactions(ctx, account_info, account_transactions)
|
print_transactions(ctx, account_info, account_transactions)
|
||||||
else:
|
else:
|
||||||
res = get(ctx, "/requisitions/")
|
res = get(ctx, "/requisitions/")
|
||||||
accounts = []
|
accounts = set()
|
||||||
for r in res["results"]:
|
for r in res["results"]:
|
||||||
accounts += r.get("accounts", [])
|
accounts.update(r.get("accounts", []))
|
||||||
for account in accounts:
|
for account in accounts:
|
||||||
account_details = get(ctx, f"/accounts/{account}")
|
account_details = get(ctx, f"/accounts/{account}")
|
||||||
account_transactions = get(ctx, f"/accounts/{account}/transactions/").get(
|
account_transactions = get(ctx, f"/accounts/{account}/transactions/").get(
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
[tool.poetry]
|
[tool.poetry]
|
||||||
name = "leggen"
|
name = "leggen"
|
||||||
version = "0.2.0"
|
version = "0.2.2"
|
||||||
description = "An Open Banking CLI"
|
description = "An Open Banking CLI"
|
||||||
authors = ["Elisiário Couto <elisiario@couto.io>"]
|
authors = ["Elisiário Couto <elisiario@couto.io>"]
|
||||||
readme = "README.md"
|
readme = "README.md"
|
||||||
|
|||||||
Reference in New Issue
Block a user