new functions, yadda yadda
This commit is contained in:
parent
620db27468
commit
95587ba68d
22
css/main.css
22
css/main.css
@ -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
2
go.mod
@ -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
|
||||
)
|
||||
|
4
main.go
4
main.go
@ -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)
|
||||
}
|
||||
|
||||
|
109
rewards.go
109
rewards.go
@ -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
|
||||
}
|
||||
|
@ -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">♥ 2020 Nils Jakobi
|
||||
- <a href="https://git.nils.zone/nils/goCake">Source Code</a>
|
||||
<div class="footer">
|
||||
♥ <a href="https://github.com/thunderstorm99/goCoinAnalyzer">Source Code</a> ♥
|
||||
</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}}
|
@ -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" .}}
|
Loading…
Reference in New Issue
Block a user