dficsv/main.go

157 lines
3.4 KiB
Go

package main
import (
"flag"
"fmt"
"log"
"os"
"strconv"
"strings"
"time"
"git.nils.zone/nils/prettify"
)
type lineEntry struct {
BlockHeight int
BlockHash string
Type string
PoolID int
Time time.Time
Amounts map[string]float64
}
func main() {
// define flags
csvFile := flag.String("csvFile", "", "specifies the path the csv file containing the transaction log")
flag.Parse()
if *csvFile == "" {
log.Fatal("please specify a csvFile using the flag -csvFile")
}
// start of program
b, err := readCSV(*csvFile)
if err != nil {
log.Fatalf("error occurred when reading csv, error is: %s", err)
}
entries, err := unmarshalCSV(b)
if err != nil {
panic(err)
}
var rewards []lineEntry
for i := range entries {
if entries[i].Type == "Rewards" {
rewards = append(rewards, entries[i])
}
}
// print out all rewards
printRewards(rewards)
}
func printRewards(rewards []lineEntry) {
// daily
daily := listRewards("2006-01-02", rewards)
// monthly
monthly := listRewards("2006-01", rewards)
// yearly
yearly := listRewards("2006", rewards)
// print rewards
log.Println("listing daily Rewards")
prettify.Print(daily)
log.Println("listing monthly Rewards")
prettify.Print(monthly)
log.Println("listing yearly Rewards")
prettify.Print(yearly)
}
func listRewards(format string, entries []lineEntry) map[string]float64 {
rewards := make(map[string]float64)
for i := range entries {
rewardsString := entries[i].Time.Format(format)
rewards[rewardsString] += entries[i].Amounts["DFI"]
}
return rewards
}
func readCSV(filename string) ([]byte, error) {
b, err := os.ReadFile(filename)
if err != nil {
return nil, err
}
return b, nil
}
func unmarshalCSV(b []byte) ([]lineEntry, error) {
// output variable
var e []lineEntry
// read all lines and do magic on each line
lines := strings.Split(string(b), "\n")
// for i := range lines {
for i := 1; i < len(lines); i++ {
// create variable for current line
var l lineEntry
l.Amounts = make(map[string]float64)
// Remove " from lines
line := strings.ReplaceAll(lines[i], `"`, ``)
// split line by comma
entries := strings.Split(line, ",")
// convert blockHeight to int
height, err := strconv.Atoi(entries[0])
if err != nil {
return nil, fmt.Errorf("can't convert blockHeight in line %d to int, error is: %s", i+1, err)
}
// get time from CSV
dateTime, err := time.Parse("02/01/2006 / 03:04 pm", entries[2])
if err != nil {
return nil, fmt.Errorf("can't convert time in line %d to time.time, error is: %s", i+1, err)
}
// convert poolID to int
if entries[5] == "" {
// empty row
entries[5] = "0"
}
poolID, err := strconv.Atoi(entries[5])
if err != nil {
return nil, fmt.Errorf("can't convert poolID in line %d to int, error is: %s", i+1, err)
}
// Split for amount and currency
amounts := strings.Split(strings.Join(entries[6:], " "), " ")
for i := range amounts {
// Split amounts and currency
ac := strings.Split(amounts[i], "@")
amountString := ac[0]
currency := ac[1]
// Parse string to float
amount, err := strconv.ParseFloat(amountString, 64)
if err != nil {
return nil, err
}
// put rewards into map
l.Amounts[currency] = amount
}
// fill l with values
l.BlockHeight = height // entries[0]
l.BlockHash = entries[1] // entries[1]
l.Type = entries[4] // entries[2]
l.PoolID = poolID // entries[3]
l.Time = dateTime
e = append(e, l)
}
return e, nil
}