Skip to content

Yet another tool to manage private finances, written in Haskell and JS

License

Notifications You must be signed in to change notification settings

thiesgerken/moneydb

Repository files navigation

MoneyDB

Yet another tool to manage private finances.

Consists of the following components:

  • REST server and a client application, both written in haskell.
  • Web app that can be built into the server binary
  • Android app

How to build

In a clean working directory make will build the server, client and the android app. It will also package the server into a debian package. Build output can be found in the dist directory. To be CI-friendly, most targets in the Makefile do not specify dependencies and therefore will not be rerun if the output already exists (even if it is outdated). In this case run make clean.

Detailed instructions for each component:

Web app

Uses the package base of npm for dependencies, which can also be managed by Yarn. The website uses Semantic UI and also makes heavy use of jQuery The code itself resides in web/src and should be processed by the web bundler Parcel because it relies on a module loader (Webpack might also work after some reconfiguring). To install the dependencies run yarn install (or npm install) in the web directory.

To be able to package the app a java script client library for the REST api exposed by moneydb-server is required. The server can generate this for you by running

moneydb-server --js > web/src/moneydb.js

There are two scripts defined in web/package.json which call parcel in two different ways:

  • yarn start (or npm run-script start) compiles it in debug-mode, i.e. without minifying the resulting java script and assets, enabling hot module replacement and so on. The command will then watch for changes in web/src to allow for more comfortable development.
  • yarn build (or npm run-script build) compiles in release-mode, i.e. with minifying and without watching for further file changes. It will also minify svg files and create the file dist/report.html with an analysis of the bundled files.

In both cases the output will go to web/dist, but only the build target empties this directory beforehand. The web app will try to make REST requests to /api/, so either use moneydb-server to serve both or configure your web server appropriately.

The project is set up to use ESLint, which you can invoke by running

yarn exec eslint src

in the web directory. Fix problems by appending --fix or --fix-dry-run to this command. It will not fix the indentation, because I like to use js-beautify for this. Linting of html files can be done by typing

yarn htmlhint "src/**/*.html"

which will launch HTMLHint.

Haskell code

To build the code you will need mysql and postgres development libraries and the Haskell tool stack, which will download the appropriate GHC and install required packages by running stack setup -j4 in the project directory. In docker you will find a Dockerfile that that can be used to create an Ubuntu 18.04 image with the neccessary dependencies pre-installed. See docker/build.sh for commands on how to build and push the image (if you are logged in to this GitLab's container registry)

stack build -j4

will then compile the server and client applications. In this case, the web/dist directory is embedded in the executable, so make sure that the directory exists. It can be empty, e.g. if the resulting binary should only be used to create moneydb.js and allow bundling of the web app (also refer to the Makefile target which compiles the server twice for this). A change in the web directory will trigger a recompilation by stack build.

stack build -j4 --flag moneydb:localwww

will not embed the web app into the executable. Instead, the server will (try to) serve everything that is not an API endpoint from ./web/dist at runtime, allowing for development of the web app without having to recompile the server after each change (use with yarn start).

Supply -jN to the stack commands above to compile with N threads.

For linting I like to use hlint and weeder. Indentation of import lists is a job for stylish-haskell.

Android app

Just import the project into Android Studio. If the Android SDK is installed, you can also try to invoke ./gradlew build from the app directory.

The app needs a client library for the API endpoints as well and searches for it in app/app/libs/moneydb-client-2.0.0.jar. There is a make target to create this library from dist/swagger.json (output of moneydb-server --spec).

How to use

moneydb-server

After compilation, you can use

stack exec moneydb-server -- --help

to run the server and show available options (note the -- to separate stack options from options passed to moneydb-server). stack install will copy the binaries to a location like ~/.local/bin and the make target will put them in dist where they can be executed directly.

If you used make to generate moneydb-server.deb you can transfer and install this package on a Ubuntu 18.04 machine (dependencies: libpq5, libmysqlclient20 and libatomic1). The package also provides a systemd unit for the server, which is enabled and started upon install.

sudo dpkg -i moneydb-server.deb
which moneydb-server
moneydb-server --help

For production use a database backend like MySQL or PostgreSQL instead of SQLite is recommended. The database connection can be configured in the config file, a stub can be found in server/moneydb.cfg. The server searches for this config file in ./moneydb.cfg and /etc/moneydb/moneydb.cfg (in that order), or a different file when using the -c option.

In production use it is recommended to backup the database regularly. If you do not like SQL dumps use moneydb-server --export and moneydb-server --import to export/import the database to/from a JSON file.

Setup PostgreSQL

SQLite is very nice for small databases (a few hundred expenses) and for development, but tends to be the bottleneck in production use. A faster alternative is PostgreSQL, which can be installed via the postgres package on Arch Linux. Its Arch wiki page is very helpful, a short summary:

Initial configuration:

sudo -u postgres -i
initdb --locale de_DE.UTF-8 -E UTF8 -D '/var/lib/postgres/data'

Start and enable the postgres service, and after becoming the postgres user again run

createuser --interactive
createdb moneydb -O [username]

If you use the same username for createuser (and createdb) as the system user (moneydb ) you will be able to connect to the database without authentication. This worked out of the box on my Arch System, but needed some tweaking on a Ubuntu machine (change everything but the first entry's method to trust in /etc/postgresql/10/main/pg_hba.conf). Make sure that the database only accepts connection from localhost (should be the default behaviour).

A suitable database configuration for moneydb-server would then be

postgresql {
 connections = 25
 host  = "localhost"
 port  = 5433
 db  = "moneydb"
 user  = ""
 pass  = ""
}

Then fill this database by moneydb-server --import or moneydb-server --demo, which have to be run as the user moneydb, i.e.

sudo -u moneydb moneydb-server --import < backup.json
sudo systemctl restart moneydb-server

moneydb-client

The client app can be invoked in the same way as the server binary. Its primary use is to deliver automatically grabbed expenses to the server (separated from the server for the likely case that you want to keep your banking credentials encrypted at home and not on a server in the internet). See the client directory for scripts which use it in combination with FinTS.

About

Yet another tool to manage private finances, written in Haskell and JS

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published