Skip to content

Instantly share code, notes, and snippets.

@2garryn
Last active May 15, 2018 10:04
Show Gist options
  • Save 2garryn/83545e1ec1874b396652c755bd9e5a8e to your computer and use it in GitHub Desktop.
Save 2garryn/83545e1ec1874b396652c755bd9e5a8e to your computer and use it in GitHub Desktop.
package main
import (
"fmt"
"flag"
"os"
"bufio"
"strings"
"golang.org/x/text/encoding/charmap"
"strconv"
// "container/list"
"crypto/md5"
"github.com/deckarep/golang-set"
"time"
// "encoding/gob"
"encoding/gob"
)
//
// Дата списания;Приход;Расход;Описание;Дата авторизации;Карта;Валюта списания;код категории продавца;Место
const CHARGE_TS = 0
const INCOME = 1
const OUTCOME = 2
const DESCR = 3
const AUTH_TS = 4
const CARD_NUMBER = 5
const CHARGE_AMOUNT = 6
const CHARGE_CURRENCY_CODE = 7
const MCC = 8
const PLACE = 9
const DB_FILEPATH = "something"
type Transaction struct {
TS time.Time;
Income float64;
Outcome float64;
Descr string;
AuthTS time.Time;
CardNumber string;
ChargeAmount float64;
ChargeCurrencyCode string;
Mcc int64;
Place string;
Md5 string;
}
type Transactions []Transaction
func main() {
filePtr := flag.String("a", "", "path to file")
flag.Parse()
add_file(filePtr)
}
func add_file(filename *string) {
var transactions Transactions
err := readDbFile(DB_FILEPATH, &transactions)
if(err != nil) {
transactions = Transactions{}
}
newTransactions := readFile(filename)
for _, t := range newTransactions {
transactions = append(transactions, t)
}
writeDbFile(DB_FILEPATH, transactions)
}
func readDbFile(filePath string, t *Transactions) error {
file, err := os.Open(filePath)
defer file.Close()
if err == nil {
decoder := gob.NewDecoder(file)
err = decoder.Decode(t)
}
fmt.Println(err)
return err
}
func writeDbFile(filePath string, t Transactions) {
file, err := os.Create(filePath)
defer file.Close()
if err == nil {
decoder := gob.NewEncoder(file)
err = decoder.Encode(t)
} else {
panic(nil)
}
}
func getAllCodes(transactions Transactions) map[int64]mapset.Set {
codes := make(map[int64]mapset.Set)
foreachOverTransactions(transactions, func(t Transaction) {
if(t.Mcc == 0) {
return
}
if(codes[t.Mcc] != nil) {
codes[t.Mcc].Add(t.Place)
} else {
codes[t.Mcc] = mapset.NewSet()
codes[t.Mcc].Add(t.Place)
}
})
return codes
}
func readFile(filename *string) Transactions {
fh, _ := os.Open(*filename)
defer fh.Close()
fileScanner := bufio.NewScanner(fh)
var parsed []string
var trans Transaction
var income float64
var outcome float64
var chargeAmount float64
var mcc int64
var err interface{} = nil
var ts time.Time
var authTs time.Time
transactions := []Transaction{}
for fileScanner.Scan() {
parsed = strings.Split(fileScanner.Text(), ";")
trans = Transaction{}
trans.Md5 = fmt.Sprintf("%x", md5.Sum([]byte(fileScanner.Text())))
ts, err = time.Parse("02.01.2006 15:04", strings.Trim(parsed[CHARGE_TS], "\""))
if(err == nil) {
trans.TS = ts
}
authTs, err = time.Parse("02.01.2006 15:04", strings.Trim(parsed[AUTH_TS], "\""))
if(err == nil) {
trans.AuthTS = authTs
}
trans.Descr = string(decode([]uint8(parsed[DESCR])))
trans.CardNumber = parsed[CARD_NUMBER]
trans.ChargeCurrencyCode = parsed[CHARGE_CURRENCY_CODE]
trans.Place = parsed[PLACE]
income, err = strconv.ParseFloat(strings.Trim(parsed[INCOME], "\""), 64)
if(err == nil) {
trans.Income = income
}
outcome, err = strconv.ParseFloat(strings.Trim(parsed[OUTCOME], "\""), 64)
if(err == nil) {
trans.Outcome = outcome
}
chargeAmount, err = strconv.ParseFloat(strings.Trim(parsed[CHARGE_AMOUNT], "\""), 64)
if(err == nil) {
trans.ChargeAmount = chargeAmount
}
mcc, err = strconv.ParseInt(strings.Trim(parsed[MCC], "\""), 10, 64)
if(err == nil) {
trans.Mcc = mcc
}
transactions = append(transactions, trans)
}
return transactions
}
func sumCurrencyChargedByMCC(trans Transactions, code int64) float64 {
sum := float64(0)
foreachOverTransactions(trans, func(t Transaction) {
if(t.Mcc == code) {
sum += t.Outcome
}
})
return sum
}
func allOutcomedMoney(trans Transactions) float64 {
sum := float64(0)
foreachOverTransactions(trans, func(t Transaction) {
sum += t.Outcome
})
return sum
}
func allIncomedMoney(trans Transactions) float64 {
sum := float64(0)
foreachOverTransactions(trans, func(t Transaction) {
sum += t.Income
})
return sum
}
func foreachOverTransactions(trans Transactions, f func(Transaction)) {
for _, t := range trans {
f(t)
}
}
// Encode from UTF8 to Windows1252
// Decode result from Windows1251 to UTF8
func decode(ba []uint8) []uint8 {
dec := charmap.Windows1252.NewEncoder()
dec2 := charmap.Windows1251.NewDecoder()
out, _ := dec.Bytes(ba)
out2, _ := dec2.Bytes(out)
return out2
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment