#!/usr/bin/env bash # # Crédit Coopératif account tools # # It fetch csv file and merge them to previous ones # It also generates a local file suitable for a feed reader # # Depends on wget, iconv set -e export CCPATH=~/ccoop LOGFILE=$CCPATH/ccoop.log # unsued unless --log option is used COOKIEJAR=$CCPATH/cookiejar # cookies, deleted on exit TMP=$CCPATH/lastpage.html # last html page, deleted on exit function parsearg() { _OPT="${1%=?*}" _VAL="${1#?*=}" } function usage() { #echo $'\n' $@ $'\n' echo "Usage: ccoop-update [options]" echo " -h|--help Display that help" echo " -q|--quiet Don't display informationnal messages" echo " --log Log everything to $LOGFILE" echo " --config Setup a config file and install cron entry" echo " --unconfig Remove config file and remove cron entry" #echo " --target= Set target filename. Defaults to $target_file" #echo "See man ccoop-update(1) for documentation." } for arg in "$@"; do parsearg $arg case $_OPT in -q|--quiet) quiet=1 continue ;; --log) log=1 continue ;; --config) isconfig=1 continue ;; --unconfig) isunconfig=1 continue ;; -h|--help) usage exit 0 ;; #--target) # target_file=$_VAL # continue #;; *) echo "Unknown option $_OPT" usage exit 22 ;; esac done # That function prints messages to stderr, unless quiet is set # It logs into $LOGFILE if log is set, no matter whether quiet is set or not function inform() { if [ -n "$quiet" ]; then if [ -n "$log" ]; then echo $@ >> $LOGFILE >&2 fi else # not quiet if [ -n "$log" ]; then echo $@ | tee -a $LOGFILE >&2 else echo $@ >&2 fi fi } function fetch() { curl --cookie $COOKIEJAR --cookie-jar $COOKIEJAR --location "$@" | iconv -f ISO-8859-1 -t UTF-8 > $TMP if [ -n "$log" ]; then cat $TMP >> $LOGFILE fi } function doconfig() { read -p "Coopanet login: " COOPLOGIN read -p "Coopanet password: " -s COOPPASSWORD mkdir -p $CCPATH echo "# coopanet configuration">$CCPATH/config echo "COOPLOGIN=$COOPLOGIN">>$CCPATH/config echo "COOPPASSWORD=$COOPPASSWORD">>$CCPATH/config echo >&2 echo "config writen to $CCPATH/config" >&2 if [[ "${0:0:1}"=="/" ]]; then # absolute path command="$0" else command="$PWD/$0" fi crontab -l | grep -v ccoop-update || echo "$(($RANDOM%60)) 6 * * * $command -q" | crontab - echo "crontab installed" >&2 } function dounconfig() { local ok if [[ -e $CCPATH/config ]]; then rm -f $CCPATH/config echo "$CCPATH/config deleted">&2 ok=1 fi if crontab -l | grep -q ccoop-update ; then crontab -l | grep -v ccoop-update | crontab - echo "crontab uninstalled" >&2 ok=1 fi if [[ -z "$ok" ]]; then echo "Allready uninstalled." >&2 fi if [[ -e "$CCPATH" ]]; then echo "Password cleared. Remove ~/ccoop manually if you want to erase history." >&2 fi exit 0 } function fetchall() { echo> $COOKIEJAR if [[ -n "$log" ]]; then echo> $LOGFILE fi inform "CURL /banque/sso/co/connexionsec.do" fetch --data "codeUtil=$COOPLOGIN&motPasse=$COOPPASSWORD&identType=MDP&pbValider=Valider" https://www.coopanet.com/banque/sso/co/connexionsec.do if grep -q "Choisissez votre mode d" $TMP; then echo "Can't log in. Check password" >&2 exit 1 fi IFS=$'\n' accountsId=(`grep numeroExterne $TMP | grep hidden | cut -d \" -f 14`) accountsNames=(`grep "" $TMP | cut -d \> -f 6 | cut -d "<" -f 1`) accountsBalances=(`grep "Consulter votre relevé" $TMP | cut -d ">" -f 3 | cut -d "<" -f 1`) unset IFS for idx in ${!accountsId[@]}; do account=${accountsId[$idx]} name=${accountsNames[$idx]} balance=${accountsBalances[$idx]} inform "$name $account $balance" inform "CURL situationcomptes.do" fetch --data "numeroExterne=$account&typeAction=2&btAction=OK" https://www.coopanet.com/banque/cpt/cpt/situationcomptes.do dateFin=`grep dateFin $TMP | cut -d \" -f 10` inform "CURL selectiontelechargement.do" fetch --data "format=3&dateDebut=01/01/2001&dateFin=$dateFin&btValider=Valider" https://www.coopanet.com/banque/cpt/cpt/selectiontelechargement.do inform "CURL telechargement.do" ppath=`grep path $TMP | cut -d \" -f 6` fetch --data "path=$ppath&zip=2&btConfirmer=Confirmer" https://www.coopanet.com/banque/cpt/cpt/telechargement.do tail -n +2 $TMP > $CCPATH/$account.`date +%Y%m%d`.csv rm -f $CCPATH/$account.last.csv ln -s $CCPATH/$account.`date +%Y%m%d`.csv $CCPATH/$account.last.csv done # logout inform "CURL /banque/sso/ssologout.do" fetch https://www.coopanet.com/banque/sso/ssologout.do # delete tmp files rm -f $COOKIEJAR $TMP } # That function updates $account.csv files, adding the latest missing entries # It dumps on stdout the new lines function updatehistory() { inform "Updating complete csv files" # merge values in $account.csv for idx in ${!accountsId[@]}; do account=${accountsId[$idx]} name=${accountsNames[$idx]} balance=${accountsBalances[$idx]} # get new lines into $account.new.csv diff -Nau $CCPATH/$account.last.csv $CCPATH/$account.csv | grep "^-" | grep -v "^---" | cut -c 2- > $CCPATH/$account.new.csv # print new entries cat $CCPATH/$account.new.csv cat $CCPATH/$account.csv >>$CCPATH/$account.new.csv mv $CCPATH/$account.new.csv $CCPATH/$account.csv done } function makefeed() { inform "Updating feeds" if [[ "${0:0:1}"=="/" ]]; then # absolute path path="`dirname $0`" else path="$PWD/`dirname $0`" fi for idx in ${!accountsId[@]}; do account=${accountsId[$idx]} name=${accountsNames[$idx]} balance=${accountsBalances[$idx]} "$path/ccoop-feeder" "$account" "$name" "$balance" > $CCPATH/$account.atom done } umask 0077 # make sure the generated files are only readable by the user if [[ -n $isconfig ]]; then doconfig fi if [[ -n $isunconfig ]]; then dounconfig fi # Make sure our temporary files are deleted on error and on exit trap "rm -f $COOKIEJAR $TMP; exit" INT TERM EXIT if [[ ! -r $CCPATH/config ]]; then echo "Use '$0 --config'" exit 1 fi if [[ `ls -l $CCPATH/config | cut -c 8-10` != "---" ]]; then echo "Security warning: config file should be chmod o-rwx" >&2 fi source $CCPATH/config if [[ -n $log ]]; then inform "Warning, $LOGFILE will contain sensitive information. You should delete it." fi fetchall updatehistory makefeed