From 2ee1b6343b0e84ed184a681f74b42e60a2949b07 Mon Sep 17 00:00:00 2001 From: Marc Ghorayeb Date: Fri, 10 Feb 2012 23:26:58 +0100 Subject: [PATCH] Several fixes. Added Weboob library as a submodule. Updated the readme. --- .gitmodules | 3 ++ README | 15 ---------- README.md | 36 +++++++++++++++++++++++ app/extensions/data/Connector.php | 38 ++++++++++++------------ app/extensions/data/connector/SG.php | 4 +-- app/libraries/weboob | 1 + app/models/Accounts.php | 44 ++++++++++++++-------------- app/models/Banks.php | 20 ++++++------- app/webroot/js/defaults/defaults.js | 12 ++++---- 9 files changed, 100 insertions(+), 73 deletions(-) create mode 100644 .gitmodules delete mode 100644 README create mode 100644 README.md create mode 160000 app/libraries/weboob diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..09ed9d7 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "app/libraries/weboob"] + path = app/libraries/weboob + url = git://git.symlink.me/pub/romain/weboob-stable.git diff --git a/README b/README deleted file mode 100644 index cd47429..0000000 --- a/README +++ /dev/null @@ -1,15 +0,0 @@ -turtl - Bank account aggregator - -Requires: -- lithium -- li3_swiftmailer -- li3_flash -- swiftmailer - -Todo: -- Bank connectors -- Graphics -- Mail summaries - -License: -You can reuse this code as you want and modify it as you seem fit. Just give the copyright when due. \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..d11032a --- /dev/null +++ b/README.md @@ -0,0 +1,36 @@ +turtl - Bank account aggregator +=============================== + + +Requiremed libraries +-------------------- +Clone the following libraries into a libraries folder (next to the main app folder). + +- lithium +```jinja +git clone git://github.com/UnionOfRAD/lithium.git +``` +- li3_swiftmailer +```jinja +git clone git://github.com/greut/li3_swiftmailer.git +``` +- li3_flash +```jinja +git clone git://github.com/rich97/li3_flash.git +``` +- swiftmailer +```jinja +git clone https://github.com/swiftmailer/swiftmailer.git +``` + +Todo +---- + +- More bank connectors based on the weboob tools. +- Graphics +- Mail summaries + +License +------- + +You can reuse this code as you want and modify it as you seem fit. Just give the copyright when due. \ No newline at end of file diff --git a/app/extensions/data/Connector.php b/app/extensions/data/Connector.php index 2f7c334..d70caea 100755 --- a/app/extensions/data/Connector.php +++ b/app/extensions/data/Connector.php @@ -12,15 +12,15 @@ abstract class Connector extends \lithium\core\Object { protected $_scripts = array( 'SG' => '/home/admin/tools/connectors/sg.py' ); - + protected $_results = array(); protected $_accounts = array(); - + protected $_header = array(); - + protected $_transactions = array(); - + protected function _init() { parent::_init(); } @@ -29,19 +29,21 @@ public function setCredentials($login, $password) { $this->_config['login'] = $login; $this->_config['password'] = $password; } - + public function scrape($account = null) { $this->_scrape($account); - if ($account) { - $this->_filterHeader(); - $this->_filterTransactions(); - } - else { - $this->_filterAccounts(); - } + if (!empty($this->_results)) { + if ($account) { + $this->_filterHeader(); + $this->_filterTransactions(); + } + else { + $this->_filterAccounts(); + } - $this->_cleanInput(); + $this->_cleanInput(); + } } public function getResults() { @@ -51,22 +53,22 @@ public function getResults() { public function getAccounts() { return $this->_accounts; } - + public function getHeader() { return $this->_header; } - + public function getTransactions() { return $this->_transactions; } - + public function __destruct() { } abstract protected function _scrape(); - + abstract protected function _filterHeader(); - + abstract protected function _filterTransactions(); abstract protected function _cleanInput(); diff --git a/app/extensions/data/connector/SG.php b/app/extensions/data/connector/SG.php index 1993d56..284494a 100755 --- a/app/extensions/data/connector/SG.php +++ b/app/extensions/data/connector/SG.php @@ -8,7 +8,7 @@ class SG extends \app\extensions\data\Connector { protected function _init() { parent::_init(); - + $this->_config['bank'] = 'SG'; } @@ -133,7 +133,7 @@ function (&$value, $field) use ($connector) { } } ); - + array_walk_recursive( $this->_transactions, function (&$value, $field) { diff --git a/app/libraries/weboob b/app/libraries/weboob new file mode 160000 index 0000000..b3e1c4f --- /dev/null +++ b/app/libraries/weboob @@ -0,0 +1 @@ +Subproject commit b3e1c4fa115ad17de4b4658f97c7ff5b1f197a2e diff --git a/app/models/Accounts.php b/app/models/Accounts.php index 4a210f2..c524ec1 100755 --- a/app/models/Accounts.php +++ b/app/models/Accounts.php @@ -29,12 +29,12 @@ class Accounts extends \app\models\AppBaseModel { 'title' => array('type' => 'string', 'default' => ''), 'bankCode' => array('type' => 'string', 'default' => ''), 'agencyCode' => array('type' => 'string', 'default' => ''), - + 'period' => array('type' => 'object'), 'period.start' => array('type' => 'date'), 'period.end' => array('type' => 'date'), 'period.activityCount' => array('type' => 'integer', 'default' => 0), - + 'balance' => array('type' => 'object'), 'balance.date' => array('type' => 'date'), 'balance.amount' => array('type' => 'float', 'default' => 0), @@ -46,7 +46,7 @@ class Accounts extends \app\models\AppBaseModel { 'snapshots' => array('type' => 'object', 'array' => true, 'default' => array()) ); - + public $validates = array( 'id' => 'notEmpty', 'user_id' => 'notEmpty', @@ -63,7 +63,7 @@ class Accounts extends \app\models\AppBaseModel { /** * Creates and returns a data parser for a given $filepath and $bank. - * + * * @see app\extensions\data\Parser * @param string $filepath Path to the bank file to be parsed. * @param string $bank Bank name which determines the file format for the parser. @@ -77,7 +77,7 @@ class Accounts extends \app\models\AppBaseModel { 'guessBank' => $guessBank, 'readFile' => true )); - + return $parser; }*/ @@ -108,7 +108,7 @@ public static function createConnector($bank, $login, $password) { */ public function makeConnector($entity) { $bank = Banks::first($entity->bank_id); - + if (empty($this->_connector) && !empty($bank)) { $this->_connector = self::createConnector( $bank->short_title, @@ -130,7 +130,7 @@ public function scrape($entity) { if (!empty($this->_connector)) { $lastAccess = $entity->portal->lastAccess->sec; $now = time(); - + // Make sure you didn't already scrape in the last hour. Let's not spam the website. //if (empty($lastAccess) || ($now - $lastAccess) > 3600) { $entity->portal->lastAccess = $now; @@ -155,10 +155,10 @@ public function fetchTransactions($entity) { return array(); } - + /** * Inputs transactions into the database for a given account. - * + * * @param object $entity * @param array $transactions List of transactions to be inserted in the database. */ @@ -167,11 +167,11 @@ public function inputTransactions($entity, array $transactions) { $account_id = (string) $entity->_id; $bank = Banks::first($entity->bank_id); $keys = compact('user_id', 'account_id'); - + foreach ($transactions as $transaction) { $data = $keys + $transaction; $t = Transactions::create($data); - + if ($t->validates()) { $t->populateDetails($bank); $t->guessCategory(); @@ -190,7 +190,7 @@ public function inputTransactions($entity, array $transactions) { * $existingAccount->mergeHeaders($newAccount) * $existingAccount->save(); * }}} - * + * * @see app\models\Accounts::buildSnapshots * @param object $entity Existing account. * @param object $source New account from which data will be copied into $entity. @@ -198,7 +198,7 @@ public function inputTransactions($entity, array $transactions) { public function mergeHeaders($destination, $source) { $date1 = $destination->balance->date->sec; $date2 = $source->balance->date->sec; - + if ($date1 < $date2) { $destination['balance']['date'] = $source['balance']['date']; $destination['balance']['amount'] = $source['balance']['amount']; @@ -218,10 +218,10 @@ public function mergeHeaders($destination, $source) { $destination->period->end = $source->period->end; } } - + /** * Returns a list of MongoIds for a given list of Accounts. - * + * * @param array $accounts */ public static function getIds($accounts) { @@ -230,14 +230,14 @@ public static function getIds($accounts) { foreach ($accounts as $account) { $ids[] = (string) $account->_id; } - + return $ids; } /** * Builds snapshots based on a per-month basis for a list of given transactions. * Stores the result in `$entity->snapshots`. - * + * * @see app\models\Accounts::buildSnapshots * @param object $entity * @todo Optimize loop. @@ -269,7 +269,7 @@ public function refresh($entity) { /** * Builds snapshots based on a per-month basis for a list of given transactions. * Stores the result in the $snapshots field. - * + * * @see app\models\Accounts::buildSnapshot * @todo Optimize loop. */ @@ -299,7 +299,7 @@ public function buildSnapshots($entity, $transactions = array()) { /** * Builds a snapshot out of a list of transactions. * A snapshot totals the debits, credits, and transaction count (activityCount). - * + * * Example: * {{{ * $transactions = Transactions::all(); @@ -307,7 +307,7 @@ public function buildSnapshots($entity, $transactions = array()) { * }}} * * Usefull when building snapshots on a per-month basis. - * + * * @see app\models\Accounts::buildSnapshots * @param array $transactions * @return array Array containing the total of debit, credit, and activityCount. @@ -323,7 +323,7 @@ public static function buildSnapshot($transactions) { return $snapshot; } - + // ****************************************** // Bridges // ****************************************** @@ -340,7 +340,7 @@ public function transactions($entity, $limit = 30) { /** * Returns a list of periods available for a list of accounts. * A period is usually a month designated by the format `mm-yyyy`. - * + * * @param array $accounts List of accounts. * @return array Periods for the accounts given. */ diff --git a/app/models/Banks.php b/app/models/Banks.php index af06198..e64ed1c 100644 --- a/app/models/Banks.php +++ b/app/models/Banks.php @@ -12,7 +12,7 @@ class Banks extends \app\models\AppBaseModel { '_id' => array('type' => 'id'), 'created' => array('type' => 'date'), 'modified' => array('type' => 'date'), - + 'title' => array('type' => 'string'), 'short_title' => array('type' => 'string'), @@ -24,20 +24,20 @@ class Banks extends \app\models\AppBaseModel { 'templates.cheque' => array('type' => 'string', 'array' => true, 'default' => array()), 'templates.virement' => array('type' => 'string', 'array' => true, 'default' => array()) ); - + public $validates = array( 'title' => 'notEmpty', 'short_title' => 'notEmpty', ); - + /** * Erase all banks and start from fresh - * + * * @return void */ public static function initialise() { self::remove(); - + $banks = array( array( 'title' => 'Société Générale', @@ -51,13 +51,13 @@ public static function initialise() { ) ) ); - + foreach ($banks as $b) { $bank = self::create($b); $bank->save(); } } - + public function templates($entity) { $templates = $entity->templates->to('array'); @@ -110,15 +110,15 @@ public function cleanTemplates($entity) { /*Banks::applyFilter('create', function($self, $params, $chain) { $defaults = array( ); - + $params['data'] = $params['data'] + $defaults; - + return $chain->next($self, $params, $chain); });*/ Banks::applyFilter('validate', function ($self, $params, $chain) { $params['entity']->cleanTemplates(); - + return $chain->next($self, $params, $chain); }); ?> \ No newline at end of file diff --git a/app/webroot/js/defaults/defaults.js b/app/webroot/js/defaults/defaults.js index 1dfcd27..58aa20b 100755 --- a/app/webroot/js/defaults/defaults.js +++ b/app/webroot/js/defaults/defaults.js @@ -14,15 +14,15 @@ var turtl = new Object(); function dump(arr,level) { var dumped_text = ""; if(!level) level = 0; - + //The padding given at the beginning of the line. var level_padding = ""; for(var j=0;j