{ "info": { "author": "Sean McLemon", "author_email": "sean.mclemon@gmail.com", "bugtrack_url": null, "classifiers": [], "description": "rbcz.py |Build Status| |Coverage Status|\n========================================\n\n``rbcz`` is a Python library for parsing the plain-text bank statements\nthat Raiffeisen Bank send out via email. It exposes a simple API to\neither parse statements stored on your local filesystem or to search\nthrough your email and retrieve them via IMAP.\n\nInstall\n-------\n\nEither retrieve from pypi using pip:\n\n::\n\n $ pip install rbcz\n\nor clone this repo, and install using ``setup.py``:\n\n::\n\n $ git clone https://github.com/smcl/rbcz.py\n $ cd rbcz.py\n $ python setup.py install\n\nMethods\n-------\n\nThere are three simple functions - ``read_statement``,\n``read_statements`` and ``read_statements_from_imap``. To parse a single\nstatement we can use the ``read_statement`` function, which takes a\nsingle parameter - the path to the bank statement on the local\nfilesystem - and returns a ``Statement`` object:\n\n::\n\n from rbcz import *\n statement = rbcz.read_statement(\"/path/to/stmt_january_czk.txt\")\n\nIf we have a number of statements locally we can use ``read_statements``\nwhich accepts a list of filenames to parse, and returns a list of\n``Statement``:\n\n::\n\n from rbcz import *\n\n statement_filenames = [\n \"stmt_jan_czk.txt\",\n \"stmt_feb_czk.txt\",\n \"stmt_mar_czk.txt\"\n ]\n\n statements = rbcz.read_statements(statement_filenames)\n\nIf we don't have all our statements stored locally we can use\n``read_statements_from_imap`` to connect to an IMAP server and search it\nfor emails from the \"info@rb.cz\" address, download and parse the\nattachments and return a list of ``Statement``.\n\n::\n\n from rbcz import *\n\n statements = read_statements_from_imap(\"imap.gmail.com\", \"my.email.address@gmail.com\", \"password123\", \"inbox\")\n\nTypes\n-----\n\nThere are two types - ``Statement`` and ``Movement``.\n\nStatement\n~~~~~~~~~\n\nA ``Statement`` represents a monthly statement:\n\n- ``account_name`` - (string) the name of the main account holder (your\n name!)\n- ``account_number`` - (string) your account number\n- ``iban`` - (string) the IBAN of your account\n- ``currency`` - (string) the currency the account holds\n- ``number`` - (int) the number of the statement (your first statement\n will be ``1``)\n- ``from_date`` - (datetime) the opening date of the statement\n- ``to_date`` - (datetime) the closing date of the statement\n- ``opening_balance`` - (Decimal) the balance at the opening date of\n the statement\n- ``income`` - (Decimal) the income you've received during the\n statement's reporting period\n- ``expenses`` - (Decimal) the expenses you've paid out during the\n statement's reporting period\n- ``closing_balance`` - (Decimal) the balance at the closing date of\n the statement\n- ``blocked`` - (Decimal) amount ringfenced for payments out\n- ``receivable`` - (Decimal) amount received but yet to clear/settle\n- ``available_balance`` - (Decimal) amount of money available to\n withdraw at the closing date of the statement\n- ``movements`` - (List of Movement) the individual cash movements\n (payments in or out) during the reporting period\n\nMovement\n~~~~~~~~\n\nA ``Movement`` is an individual transaction - for example an ATM\nwithdrawal or Debit Card payment. Each ``Statement`` will have a list of\n``Movement`` called ``movements`` for all the transactions during the\nreporting period. Each ``Movement`` has the following: \\* ``number`` -\n(int) id of the movement in the current statement \\* ``amount`` -\n(Decimal) amount of the thing \\* ``date_deducted`` - (datetime) the date\nthe transaction was submitted originally \\* ``date_completed`` -\n(datetime) the date + time the transaction was finalised at \\*\n``counterparty_account_number`` - (string) the account the payment was\nsent to or received from \\* ``counterparty_details`` - (string)\ninformation about the account the payment was sent to or received from,\nif available \\* ``narrative`` - (string) additional information about\nthe transaction \\* ``transaction_type`` - (string) what type of\ntransaction occurred \\* ``specific_symbol`` - (string) specific symbol\nfor movement \\* ``variable_symbol`` - (string) variable symbol for\nmovement \\* ``constant_symbol`` - (string) constant symbol for movement\n\nExample\n=======\n\nThe following script will attempt to parse all the statements in the\n``./rb`` directory, then take the closing balance and high/low water\nmarks of each period and plot it on a graph.\n\n::\n\n #!/usr/bin/python\n\n # system/lib imports\n import os\n import numpy as np\n import matplotlib.pyplot as plt\n from matplotlib.dates import YearLocator, MonthLocator, DateFormatter, drange, date2num\n from numpy import arange\n\n # rbcz library\n from rbcz import *\n\n # load and sort the statements\n statements = sorted(\n rbcz.read_statements([ \"./rb/\" + f for f in os.listdir(\"./rb\") ]),\n key=lambda stmt: stmt.from_date)\n\n # function to deterine high/low-water mark on account\n def high_low_water(stmt):\n bal = stmt.opening_balance\n hwm = bal\n lwm = bal\n for m in stmt.movements:\n bal += m.amount\n if bal > hwm:\n hwm = bal\n if bal < lwm:\n lwm = bal\n return (lwm, hwm)\n\n #plt.gca().set_color_cycle(['green', 'black', 'red'])\n\n\n # extract high/low-water marks\n water_marks = [ high_low_water(s) for s in statements ]\n low_water_marks = [ wm[0] for wm in water_marks ]\n high_water_marks = [ wm[1] for wm in water_marks ]\n\n # extract closing balance and dates\n closing_balances = [ s.closing_balance for s in statements ]\n dates = date2num([ s.from_date for s in statements ])\n\n # prepare and display the chart using matplotlib\n y = arange(len(dates)*1.0)\n\n # plot the data\n fig, ax = plt.subplots()\n ax.set_color_cycle(['green', 'black', 'red'])\n ax.plot_date(dates, high_water_marks, \"o-\")\n ax.plot_date(dates, closing_balances, \"o-\")\n ax.plot_date(dates, low_water_marks, \"o-\")\n\n # fix up the axes\n ax.xaxis.set_major_locator(YearLocator())\n ax.xaxis.set_minor_locator(MonthLocator())\n ax.xaxis.set_major_formatter(DateFormatter('%Y-%m-%d'))\n\n ax.fmt_xdata = DateFormatter('%Y-%m-%d')\n fig.autofmt_xdate()\n\n # add a legend\n ax.legend(['highest', 'closing', 'lowest'], loc='upper left')\n\n plt.show()\n\nDepending on the content of the bank statements this will generate a\ngraph like the following:\n\n.. figure:: rbcz.png?raw=true\n :alt: rbcz.png\n\n rbcz.png\n\nTODO\n====\n\n- get coverage to 100%\n- decide if error parsing an imap statement should be eaten, printed or\n an exception\n- check if it's possible to improve the parsing - there are a LOT of\n regexes that I throw around and it's not pretty...\n- check if anyone I know gets Czech statements, see if we can parse\n them too. Is there any other languages - German?\n- check if it works for non-Czech-Republic Raiffeisen\n\n.. |Build Status| image:: https://api.travis-ci.org/smcl/rbcz.py.svg?branch=master\n :target: https://travis-ci.org/smcl/rbcz.py\n.. |Coverage Status| image:: https://coveralls.io/repos/github/smcl/rbcz.py/badge.svg\n :target: https://coveralls.io/github/smcl/rbcz.py?branch=master", "description_content_type": null, "docs_url": null, "download_url": "https://github.com/smcl/rbcz.py/tarball/0.6", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "https://github.com/smcl/rbcz.py", "keywords": "banking,raiffeisen,czech,cz", "license": "UNKNOWN", "maintainer": null, "maintainer_email": null, "name": "rbcz", "package_url": "https://pypi.org/project/rbcz/", "platform": "UNKNOWN", "project_url": "https://pypi.org/project/rbcz/", "project_urls": { "Download": "https://github.com/smcl/rbcz.py/tarball/0.6", "Homepage": "https://github.com/smcl/rbcz.py" }, "release_url": "https://pypi.org/project/rbcz/0.6/", "requires_dist": null, "requires_python": null, "summary": "library for interacting with Czech Raiffeisen Bank's text bank statements", "version": "0.6" }, "last_serial": 2431695, "releases": { "0.1": [ { "comment_text": "", "digests": { "md5": "8132f487cc4eafba0baad612ab3c4532", "sha256": "52ee6763d8e3fc8f11259bd8a079815b16ed65c5cd714c8eb3d2d10d2881db2a" }, "downloads": -1, "filename": "rbcz-0.1.tar.gz", "has_sig": false, "md5_digest": "8132f487cc4eafba0baad612ab3c4532", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 3822, "upload_time": "2016-10-12T21:28:46", "url": "https://files.pythonhosted.org/packages/e1/76/73a8890ab3bb3138731f30203016917c3a61295aaaf65158b86b8059791f/rbcz-0.1.tar.gz" } ], "0.2": [ { "comment_text": "", "digests": { "md5": "14545b12d408da987d0df8fa47290591", "sha256": "647f28073ac8c80ba0bf46689b6e134931c9dd7a5675dea75341a55cec3f1eb4" }, "downloads": -1, "filename": "rbcz-0.2.tar.gz", "has_sig": false, "md5_digest": "14545b12d408da987d0df8fa47290591", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 4228, "upload_time": "2016-10-13T14:14:29", "url": "https://files.pythonhosted.org/packages/39/29/d2d78d1e181aa237de26e0b24b8f781f19b502feff4079bbf21fe4b3234f/rbcz-0.2.tar.gz" } ], "0.3": [ { "comment_text": "", "digests": { "md5": "c971bb971960bb0459da37835512cb4a", "sha256": "c5efd5eac4658b120cdc747d39663a567ee97fe638d3efb9ce554c98600f6f85" }, "downloads": -1, "filename": "rbcz-0.3.tar.gz", "has_sig": false, "md5_digest": "c971bb971960bb0459da37835512cb4a", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 4226, "upload_time": "2016-10-13T14:26:59", "url": "https://files.pythonhosted.org/packages/66/ff/38222b191b2af1d1383065e0557778b590b88f481e6c3ab4c0218c57f380/rbcz-0.3.tar.gz" } ], "0.4": [ { "comment_text": "", "digests": { "md5": "85ffa62f4044b2a1d4d3bf2556e9438f", "sha256": "4d69fb9c32d856b79523565c3e5f5419eaf803e1e7e0a4386c5845d48b4ff53d" }, "downloads": -1, "filename": "rbcz-0.4.tar.gz", "has_sig": false, "md5_digest": "85ffa62f4044b2a1d4d3bf2556e9438f", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 5637, "upload_time": "2016-10-19T15:22:03", "url": "https://files.pythonhosted.org/packages/96/ae/74a0c350c7841ce4fa28b8762693897ebe56e6f5b65c6b8ec3ef54771fa3/rbcz-0.4.tar.gz" } ], "0.5": [ { "comment_text": "", "digests": { "md5": "232d15a75ee670b5bbc841c4547b48f5", "sha256": "964f7be4f785c4e68da9101a50ef2611d843ba5f8bf99c72caa700d19dd3236b" }, "downloads": -1, "filename": "rbcz-0.5.tar.gz", "has_sig": false, "md5_digest": "232d15a75ee670b5bbc841c4547b48f5", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 5786, "upload_time": "2016-10-21T13:35:57", "url": "https://files.pythonhosted.org/packages/70/d6/93c0aa7e004d65e51fb6aa77bb24e832ff3df97a4a2f85d718481806d19a/rbcz-0.5.tar.gz" } ], "0.6": [ { "comment_text": "", "digests": { "md5": "daa072667e139760ded012a0746d2914", "sha256": "61e8a61af96ee1c6e5848346e6b74d1e35f7d82dced778dca97a366c825a6b4c" }, "downloads": -1, "filename": "rbcz-0.6.tar.gz", "has_sig": false, "md5_digest": "daa072667e139760ded012a0746d2914", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 8629, "upload_time": "2016-10-30T16:54:15", "url": "https://files.pythonhosted.org/packages/11/de/047c834fb7d1130b715ef7793701813ebd2b3ad83fa0f00e2912658ddfbd/rbcz-0.6.tar.gz" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "daa072667e139760ded012a0746d2914", "sha256": "61e8a61af96ee1c6e5848346e6b74d1e35f7d82dced778dca97a366c825a6b4c" }, "downloads": -1, "filename": "rbcz-0.6.tar.gz", "has_sig": false, "md5_digest": "daa072667e139760ded012a0746d2914", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 8629, "upload_time": "2016-10-30T16:54:15", "url": "https://files.pythonhosted.org/packages/11/de/047c834fb7d1130b715ef7793701813ebd2b3ad83fa0f00e2912658ddfbd/rbcz-0.6.tar.gz" } ] }