new functions, yadda yadda

This commit is contained in:
Nils Stinnesbeck 2020-11-15 20:46:32 +01:00
parent 620db27468
commit 95587ba68d
Signed by: nils
GPG Key ID: 86D4882C6C6CA48B
6 changed files with 179 additions and 59 deletions

View File

@ -121,3 +121,25 @@ nav li a:hover {
.item {
margin: auto;
}
.table {
border-collapse:collapse;
border-spacing:0;
margin: 0 auto;
width: min-content + 20px;
margin-bottom: 10%;
}
.left {
text-align: left;
}
.right {
text-align: right
}
.table td, .table th {
border-color:black;
border-style:solid;
border-width:2px
}

2
go.mod
View File

@ -3,8 +3,10 @@ module git.nils.zone/nils/goCake
go 1.15
require (
git.nils.zone/nils/prettify v0.0.4
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/kr/pretty v0.1.0 // indirect
github.com/lucasb-eyer/go-colorful v1.0.3
github.com/stretchr/testify v1.6.1
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 // indirect
)

View File

@ -15,9 +15,9 @@ func main() {
http.Handle("/css/", http.StripPrefix("/css/", http.FileServer(http.Dir("css"))))
// when navigating to /home it should serve the home page
// http.HandleFunc("/", Home)
http.HandleFunc("/", Rewards)
http.HandleFunc("/", Home)
http.HandleFunc("/rewards", Rewards)
http.HandleFunc("/table", Rewards)
http.ListenAndServe(getPort(), nil)
}

View File

@ -2,11 +2,15 @@ package main
import (
"errors"
"fmt"
"io/ioutil"
"log"
"net/http"
"strconv"
"strings"
"time"
"github.com/lucasb-eyer/go-colorful"
)
type line struct {
@ -19,16 +23,28 @@ type line struct {
Reference string
}
type rewards struct {
Staking map[time.Month]string
Confectionery map[time.Month]string
LapisDFI map[time.Month]string
Lapis map[time.Month]string
Referral map[time.Month]string
}
// Rewards needs a comment
func Rewards(w http.ResponseWriter, r *http.Request) {
type data struct {
Title string
Uploaded bool
Success bool
Rewards map[time.Month]string
Rewards rewards
CumulativeRewards map[time.Month]string
Color string
ColorAlt string
ColorAltAlt string
Currency string
ErrorText string
Lending bool
}
// set common attributes
@ -48,32 +64,54 @@ func Rewards(w http.ResponseWriter, r *http.Request) {
case http.MethodPost:
// upload the file that was posted here
var success bool = false
var e string
lines, err := uploadFile(w, r)
if err == nil {
success = true
} else {
e = err.Error()
}
// prepare data for usage
var color string
var currency string
var rewards map[time.Month]string
var rewards rewards
if success == true {
currency = lines[1].Cryptocurrency
color, _ = getCurrencyOpts(currency)
color, _, d.Lending = getCurrencyOpts(currency)
rewards = monthlyRewardOverview(lines)
}
// prettify.Print(rewards)
d.Uploaded = true
d.Success = success
d.Rewards = rewards
d.Rewards.Staking = rewards.Staking
d.Rewards.Confectionery = rewards.Confectionery
d.Rewards.Lapis = rewards.Lapis
d.Rewards.LapisDFI = rewards.LapisDFI
d.Rewards.Referral = rewards.Referral
d.Color = color
d.ColorAlt = getOtherColors(color, 2)
d.ColorAltAlt = getOtherColors(color, 4)
d.Currency = currency
d.ErrorText = e
render(w, "rewards.html", d)
}
// create a new line instance
}
func getOtherColors(color string, factor float64) string {
col, err := colorful.Hex(color)
if err != nil {
log.Fatal(err)
}
// get r,g,b from color
r, g, b := col.LinearRgb()
// return color reduced in "brightness" by factor of f
return colorful.LinearRgb(r/factor, g/factor, b/factor).Hex()
}
func uploadFile(w http.ResponseWriter, r *http.Request) ([]line, error) {
// Maximum upload of 10 MB files
r.ParseMultipartForm(10 << 20)
@ -81,7 +119,7 @@ func uploadFile(w http.ResponseWriter, r *http.Request) ([]line, error) {
// Get handler for filename, size and headers
file, handler, err := r.FormFile("csvFile")
if err != nil {
return nil, err
return nil, errors.New("please upload a .csv file")
}
defer file.Close()
@ -91,30 +129,37 @@ func uploadFile(w http.ResponseWriter, r *http.Request) ([]line, error) {
// accept this gift and read content of file
fileContents, err := ioutil.ReadAll(file)
if err != nil {
fmt.Println("file was uploaded but can't be read! 1", err)
return nil, err
}
// read uploaded file
lines := readUploadedFile(fileContents)
lines, err := readUploadedFile(fileContents)
if err != nil {
return nil, fmt.Errorf("the .csv file could not be read, error was: %s", err)
}
return lines, err
}
return nil, errors.New("please only upload .csv files")
}
func getCurrencyOpts(currency string) (color string, precision int) {
func getCurrencyOpts(currency string) (color string, precision int, lending bool) {
// set default precision
precision = 8
lending = false
// set other options according to the coin
switch currency {
case "BTC": // Bitcoin
color = "#F7931A"
lending = true
case "DASH":
color = "#008de4"
case "DFI": // DeFiChain
color = "#fd0bb0"
case "ETH": // Ethereum
color = "#627eea"
lending = true
precision = 18
case "PIVX":
color = "#5e4778"
@ -123,30 +168,49 @@ func getCurrencyOpts(currency string) (color string, precision int) {
color = "#24b852"
case "USDT": // Tether
color = "#26a17b"
lending = true
precision = 6
}
return color, precision
return color, precision, lending
}
func monthlyRewardOverview(lines []line) map[time.Month]string {
func monthlyRewardOverview(lines []line) rewards {
// create a map to hold all months' sums
sums := make(map[time.Month]float64)
staking := make(map[time.Month]float64)
confectionery := make(map[time.Month]float64)
lapisDFI := make(map[time.Month]float64)
lapis := make(map[time.Month]float64)
referral := make(map[time.Month]float64)
// loop through all lines
for i := range lines {
// filter out operations
switch lines[i].Operation {
case "Staking reward ", "Confectionery Lapis DFI Bonus ", "Lapis DFI Bonus ", "Lapis reward ", "Referral reward ":
sums[lines[i].Date.Month()] += lines[i].Amount
case "Staking reward":
staking[lines[i].Date.Month()] += lines[i].Amount
case "Confectionery Lapis DFI Bonus":
confectionery[lines[i].Date.Month()] += lines[i].Amount
case "Lapis DFI Bonus":
lapisDFI[lines[i].Date.Month()] += lines[i].Amount
case "Lapis reward":
lapis[lines[i].Date.Month()] += lines[i].Amount
case "Referral reward":
referral[lines[i].Date.Month()] += lines[i].Amount
}
}
// get precision for specific coin
_, precision := getCurrencyOpts(lines[0].Cryptocurrency)
_, precision, _ := getCurrencyOpts(lines[0].Cryptocurrency)
// fill empty data with zeroes
sumsString := fillSums(sums, precision)
r := rewards{
Staking: fillSums(staking, precision),
Confectionery: fillSums(confectionery, precision),
LapisDFI: fillSums(lapisDFI, precision),
Lapis: fillSums(lapis, precision),
Referral: fillSums(referral, precision),
}
return sumsString
return r
}
func fillSums(s map[time.Month]float64, precision int) map[time.Month]string {
@ -166,12 +230,13 @@ func fillSums(s map[time.Month]float64, precision int) map[time.Month]string {
return sumsString
}
func readUploadedFile(fileContents []byte) []line {
func readUploadedFile(fileContents []byte) ([]line, error) {
var lines []line
csvLines := strings.Split(string(fileContents), "\n")
// loop through all lines (except headers)
for _, csvLine := range csvLines[1:] {
if csvLine != "" {
// split arguments by comma
csvArgs := strings.Split(csvLine, ",")
@ -187,7 +252,7 @@ func readUploadedFile(fileContents []byte) []line {
var err error
l.Date, err = time.Parse(time.RFC3339, csvArgs[0])
if err != nil {
panic(err)
return nil, err
}
l.Operation = csvArgs[1]
l.Cryptocurrency = csvArgs[2]
@ -197,14 +262,6 @@ func readUploadedFile(fileContents []byte) []line {
l.Reference = csvArgs[6]
lines = append(lines, l)
}
return lines
}
func uploadHandler(w http.ResponseWriter, r *http.Request) {
switch r.Method {
case "GET":
render(w, "upload", nil)
case "POST":
uploadFile(w, r)
}
return lines, nil
}

View File

@ -19,7 +19,7 @@
<ul>
{{ if .Title}}
<!-- set current tab active, according to title -->
<!-- <li><a {{ if (eq .Title "Home") }}class="active"{{end}} href="/">Home</a></li> -->
<li><a {{ if (eq .Title "Home") }}class="active"{{end}} href="/">Home</a></li>
<!-- <li><a {{ if (eq .Title "Rewards") }}class="active"{{end}} href="rewards">Monthly Rewards</a></li> -->
<!-- <li><a {{ if (eq .Title "Graphs") }}class="active"{{end}} href="graphs">Graphs</a></li> -->
<li><a {{ if (eq .Title "Monthly Rewards") }}class="active"{{end}} href="rewards">Monthly Rewards</a></li>
@ -29,8 +29,8 @@
{{end}}
{{define "footer"}}
<div class="footer">&hearts; 2020 Nils Jakobi
- <a href="https://git.nils.zone/nils/goCake">Source Code</a>
<div class="footer">
&hearts; <a href="https://github.com/thunderstorm99/goCoinAnalyzer">Source Code</a> &hearts;
</div>
</body>
</html>
@ -46,23 +46,59 @@
var rewardOptions = {
title: {"text":"Monthly Rewards","subtext":"{{.Currency}}"},
tooltip: {"show":true},
legend: {"show":false},
legend: {"show":true},
dataZoom:[{"type":"inside"}],
xAxis: {{ template "xAxis" . }}
yAxis: [{}],
series: [{{template "series" . }}],
color: ["{{.Color}}"],
color: ["{{.Color}}","{{.ColorAlt}}","{{.ColorAltAlt}}"],
};
rewardChart.setOption(rewardOptions);
</script>
{{ end }}
{{define "xAxis"}}
[{"data":[ {{ range $month, $amount := .Rewards}}"{{ $month }}",{{ end }}]}],
[{"data":[ {{ range $month, $amount := .Rewards.Staking}}"{{ $month }}",{{ end }}]}],
{{end}}
{{define "series"}}
{"name":"{{.Currency}}","type":"bar","waveAnimation":false,"data":[
{{ range $month, $amount := .Rewards}}{"value": "{{ $amount }}" },{{ end }}
{{if .Lending}}
// Lending coins
{"name":"Lapis reward","type":"bar","stack":"stackA","waveAnimation":false,"data":[
{{ range $month, $amount := .Rewards.Lapis}}{"value": "{{ $amount }}" },{{ end }}
]},
{"name":"Referral reward","type":"bar","stack":"stackA","waveAnimation":false,"data":[
{{ range $month, $amount := .Rewards.Referral}}{"value": "{{ $amount }}" },{{ end }}
]},
{{else}}
// Stakeable coins
{"name":"Staking Rewards","type":"bar","stack":"stackA","waveAnimation":false,"data":[
{{ range $month, $amount := .Rewards.Staking}}{"value": "{{ $amount }}" },{{ end }}
]},
{"name":"Lapis DFI Bonus","type":"bar","stack":"stackA","waveAnimation":false,"data":[
{{ range $month, $amount := .Rewards.LapisDFI}}{"value": "{{ $amount }}" },{{ end }}
]},
{"name":"Confectionery Lapis DFI Bonus","type":"bar","stack":"stackA","waveAnimation":false,"data":[
{{ range $month, $amount := .Rewards.Confectionery}}{"value": "{{ $amount }}" },{{ end }}
]},
{{end}}
{{end}}
{{define "table"}}
<table class="table">
<thead>
<tr>
<th>Month</th>
<th>{{.Currency}}</th>
</tr>
</thead>
<tbody>
{{ range $month, $amount := .Rewards.Staking}}
<tr>
<td class="left">{{ $month }}</td>
<td class="right">{{ $amount }}</td>
</tr>
{{ end }}
</tbody>
</table>
{{end}}

View File

@ -14,12 +14,15 @@
{{if .Uploaded}}
<!-- Uploaded but not successful -->
<div class="err">
<p>Please only upload .csv Files!</p>
{{if ne .ErrorText ""}}
<p>{{.ErrorText}}</p>
{{end}}
</div>
{{end}}
{{else}}
<!-- successful -->
{{template "barGraph" .}}
<!-- {{template "table" .}} -->
{{end}}
</div>
{{template "footer" .}}