feat(fava.accounts.minion): Add truelayer importer
Truelayer is a platform that connects to many European financial
institutions, including all the ones I care about! I plan to make this
generic over accounts in the future, but for now it's awesome to have a
proof-of-concept for importers working on a single account...
Change-Id: I1b51da2952a666316a68c4dae913b5cdfae2718a
Reviewed-on: https://git.clicks.codes/c/Infra/NixFiles/+/805
Tested-by: Skyler Grey <minion@clicks.codes>
Reviewed-by: Skyler Grey <minion@clicks.codes>
diff --git a/systems/x86_64-linux/teal/clicks.services.fava.credentials.truelayer_client_secret.age b/systems/x86_64-linux/teal/clicks.services.fava.credentials.truelayer_client_secret.age
new file mode 100644
index 0000000..aba1823
--- /dev/null
+++ b/systems/x86_64-linux/teal/clicks.services.fava.credentials.truelayer_client_secret.age
@@ -0,0 +1,12 @@
+age-encryption.org/v1
+-> piv-p256 xE4ypg AvXds3fQckoyJX7ngCsw6qEsS1eqyTrrZDfqCOtYPwyw
+9JrqfxKrdrbKU/GEJNXWQnvm7LaSstJI1+QrdxU8WeA
+-> piv-p256 Hpt/+Q ApIWBJsxqUVP20vGfP9Wk46+0dOQB7GBiDKgXIkuAszL
+OSyjcTm/68lT9YgcYwZInW91cTycFDbNFPqa1GOEkVs
+-> piv-p256 zfskmQ A29S1Bw/JdpP9q+lXiOUL5Jx++o24OAqqQAEh22kVIjk
++asGJnE/9hBzXRBxXsjV35Y2mPCMIMUKNZu+DGD/9+w
+-> `}-jU-grease R)E o I|QlCYwi
+AhsxhCITkpnW4sWLfZqaqXmdIsOxBsqpVqUcTlblRF0fAIlTSw1Wc62W/U48WcqU
+a3YP4hceJqSFPajJhzUQiCCI+B0
+--- yZAwEUb6evblHmLnvshoptetkfghChxmDZ33N/pVfA0
+÷ÑÝf=âKĪc%«@ÞTõ:±ÆX»w0²61XÛ"YÜ@T9MÕy¿×Ò±3äDõêZ.r¹jêä
\ No newline at end of file
diff --git a/systems/x86_64-linux/teal/default.nix b/systems/x86_64-linux/teal/default.nix
index a97ccd8..0bd7bd4 100644
--- a/systems/x86_64-linux/teal/default.nix
+++ b/systems/x86_64-linux/teal/default.nix
@@ -176,7 +176,14 @@
};
fava = {
enable = true;
+ extraPythonPackages = [
+ pkgs.clicks.beancount-autobean
+ pkgs.clicks.beancount-smart_importer
+ ];
tailscaleAuth = true;
+ credentials = {
+ truelayer_client_secret = config.age.secrets."clicks.services.fava.credentials.truelayer_client_secret".path;
+ };
accounts = {
"clicks" = lib.home-manager.hm.dag.entryAnywhere {
name = "Clicks Codes";
@@ -189,6 +196,34 @@
"minion" = lib.home-manager.hm.dag.entryBetween [ "testing" ] [ "clicks" ] {
name = "Skyler Grey";
beancountExtraOptions.operating_currency = "GBP";
+ favaExtraOptions = {
+ invert-income-liabilities-equity = "true";
+ auto-reload = "true";
+ import-config = builtins.toString (pkgs.writeText "minion-imports.py" ''
+ import autobean.truelayer
+ from smart_importer import apply_hooks, PredictPayees, PredictPostings
+
+ import os
+ import pathlib
+
+ with open(pathlib.Path(os.environ["CREDENTIALS_DIRECTORY"]) / pathlib.Path("truelayer_client_secret")) as f:
+ truelayer_client_secret = f.read().strip()
+
+ CONFIG = [
+ apply_hooks(
+ autobean.truelayer.Importer(
+ "fava-228732",
+ truelayer_client_secret
+ ),
+ [
+ PredictPayees(),
+ PredictPostings(),
+ ]
+ )
+ ]
+ '');
+ import-dirs = "/var/lib/private/fava/minion/";
+ };
};
"testing" = lib.home-manager.hm.dag.entryAfter [ "clicks" ] {
name = "Test Data - May Be Wiped At Any Time";
@@ -250,8 +285,12 @@
system.stateVersion = "24.05";
+ age.secrets."clicks.networking.tailscale.authKeyFile".rekeyFile = ./clicks.networking.tailscale.authKeyFile.age;
+
age.secrets."clicks.security.acme.defaults.environmentFile".rekeyFile = ./clicks.security.acme.defaults.environmentFile.age;
+ age.secrets."clicks.services.fava.credentials.truelayer_client_secret".rekeyFile = ./clicks.services.fava.credentials.truelayer_client_secret.age;
+
age.secrets."clicks.services.headscale.oidc.client_secret_path" = {
rekeyFile = ./clicks.services.headscale.oidc.client_secret_path.age;
group = "headscale";
@@ -272,6 +311,4 @@
group = "headscale";
mode = "440";
};
-
- age.secrets."clicks.networking.tailscale.authKeyFile".rekeyFile = ./clicks.networking.tailscale.authKeyFile.age;
}