package main
|
|
|
|
import (
|
|
"encoding/json"
|
|
"fmt"
|
|
"net/http"
|
|
"sort"
|
|
"strconv"
|
|
"time"
|
|
|
|
"gopkg.in/mgo.v2/bson"
|
|
|
|
"github.com/gorilla/mux"
|
|
)
|
|
|
|
type Routes []Route
|
|
|
|
var routes = Routes{
|
|
Route{
|
|
"Index",
|
|
"GET",
|
|
"/",
|
|
Index,
|
|
},
|
|
Route{
|
|
"Stats",
|
|
"Get",
|
|
"/stats",
|
|
Stats,
|
|
},
|
|
Route{
|
|
"AllAddresses",
|
|
"Get",
|
|
"/alladdresses",
|
|
AllAddresses,
|
|
},
|
|
Route{
|
|
"Blocks",
|
|
"Get",
|
|
"/blocks/{page}/{count}",
|
|
Blocks,
|
|
},
|
|
Route{
|
|
"Txs",
|
|
"Get",
|
|
"/txs/{page}/{count}",
|
|
Txs,
|
|
},
|
|
Route{
|
|
"Addresses",
|
|
"Get",
|
|
"/addresses/{page}/{count}",
|
|
Addresses,
|
|
},
|
|
Route{
|
|
"Block",
|
|
"GET",
|
|
"/block/{height}",
|
|
Block,
|
|
},
|
|
Route{
|
|
"Tx",
|
|
"GET",
|
|
"/tx/{txid}",
|
|
Tx,
|
|
},
|
|
Route{
|
|
"Address",
|
|
"GET",
|
|
"/address/{hash}",
|
|
Address,
|
|
},
|
|
Route{
|
|
"AddressNetwork",
|
|
"GET",
|
|
"/address/network/{address}",
|
|
AddressNetwork,
|
|
},
|
|
Route{
|
|
"BlockSankey",
|
|
"GET",
|
|
"/block/{height}/sankey",
|
|
BlockSankey,
|
|
},
|
|
Route{
|
|
"TxSankey",
|
|
"GET",
|
|
"/tx/{txid}/sankey",
|
|
TxSankey,
|
|
},
|
|
Route{
|
|
"AddressSankey",
|
|
"GET",
|
|
"/address/sankey/{address}",
|
|
AddressSankey,
|
|
},
|
|
Route{
|
|
"NetworkMap",
|
|
"Get",
|
|
"/map",
|
|
NetworkMap,
|
|
},
|
|
Route{
|
|
"GetTotalHourAnalysis",
|
|
"Get",
|
|
"/totalhouranalysis",
|
|
GetTotalHourAnalysis,
|
|
},
|
|
Route{
|
|
"GetLast24HourAnalysis",
|
|
"Get",
|
|
"/last24hour",
|
|
GetLast24HourAnalysis,
|
|
},
|
|
Route{
|
|
"GetLast7DayAnalysis",
|
|
"Get",
|
|
"/last7day",
|
|
GetLast7DayAnalysis,
|
|
},
|
|
Route{
|
|
"GetLast7DayHourAnalysis",
|
|
"Get",
|
|
"/last7dayhour",
|
|
GetLast7DayHourAnalysis,
|
|
},
|
|
Route{
|
|
"GetLastMonthsAnalysis",
|
|
"Get",
|
|
"/lastmonths/{count}",
|
|
GetLastMonthsAnalysis,
|
|
},
|
|
Route{
|
|
"GetAddressTimeChart",
|
|
"GET",
|
|
"/addresstimechart/{hash}",
|
|
GetAddressTimeChart,
|
|
},
|
|
}
|
|
|
|
//ROUTES
|
|
|
|
func Index(w http.ResponseWriter, r *http.Request) {
|
|
fmt.Fprintln(w, "ask for recommendations in /r")
|
|
//http.FileServer(http.Dir("./web"))
|
|
}
|
|
|
|
/*
|
|
func NewUser(w http.ResponseWriter, r *http.Request) {
|
|
ipFilter(w, r)
|
|
decoder := json.NewDecoder(r.Body)
|
|
var newUser UserModel
|
|
err := decoder.Decode(&newUser)
|
|
check(err)
|
|
defer r.Body.Close()
|
|
|
|
saveUser(userCollection, newUser)
|
|
|
|
fmt.Println(newUser)
|
|
fmt.Fprintln(w, "new user added: ", newUser.ID)
|
|
}
|
|
*/
|
|
func Stats(w http.ResponseWriter, r *http.Request) {
|
|
ipFilter(w, r)
|
|
|
|
stats := getStats()
|
|
|
|
jsonResp, err := json.Marshal(stats)
|
|
check(err)
|
|
|
|
fmt.Fprintln(w, string(jsonResp))
|
|
}
|
|
func AllAddresses(w http.ResponseWriter, r *http.Request) {
|
|
ipFilter(w, r)
|
|
|
|
nodes := []NodeModel{}
|
|
iter := nodeCollection.Find(bson.M{"type": "address"}).Limit(10000).Iter()
|
|
err := iter.All(&nodes)
|
|
|
|
//convert []resp struct to json
|
|
jsonNodes, err := json.Marshal(nodes)
|
|
check(err)
|
|
|
|
fmt.Fprintln(w, string(jsonNodes))
|
|
}
|
|
func Blocks(w http.ResponseWriter, r *http.Request) {
|
|
ipFilter(w, r)
|
|
vars := mux.Vars(r)
|
|
page, err := strconv.Atoi(vars["page"])
|
|
check(err)
|
|
count, err := strconv.Atoi(vars["count"])
|
|
check(err)
|
|
|
|
blocks := []BlockModel{}
|
|
err = blockCollection.Find(bson.M{}).Skip((page - 1) * 20).Limit(count).Sort("-$natural").All(&blocks)
|
|
check(err)
|
|
|
|
for _, block := range blocks {
|
|
//blockheight := strconv.FormatInt(block.Height, 10)
|
|
blockheight := block.Height
|
|
txs := []TxModel{}
|
|
err = txCollection.Find(bson.M{"blockheight": blockheight}).All(&txs)
|
|
block.Txs = txs
|
|
}
|
|
|
|
//convert []resp struct to json
|
|
jsonData, err := json.Marshal(blocks)
|
|
check(err)
|
|
|
|
fmt.Fprintln(w, string(jsonData))
|
|
}
|
|
func Txs(w http.ResponseWriter, r *http.Request) {
|
|
ipFilter(w, r)
|
|
vars := mux.Vars(r)
|
|
page, err := strconv.Atoi(vars["page"])
|
|
check(err)
|
|
count, err := strconv.Atoi(vars["count"])
|
|
check(err)
|
|
|
|
txs := []TxModel{}
|
|
err = txCollection.Find(bson.M{}).Skip((page - 1) * 20).Limit(count).Sort("-$natural").All(&txs)
|
|
check(err)
|
|
|
|
//convert []resp struct to json
|
|
jsonData, err := json.Marshal(txs)
|
|
check(err)
|
|
|
|
fmt.Fprintln(w, string(jsonData))
|
|
}
|
|
func Addresses(w http.ResponseWriter, r *http.Request) {
|
|
ipFilter(w, r)
|
|
vars := mux.Vars(r)
|
|
page, err := strconv.Atoi(vars["page"])
|
|
check(err)
|
|
count, err := strconv.Atoi(vars["count"])
|
|
check(err)
|
|
|
|
addresses := []AddressModel{}
|
|
err = addressCollection.Find(bson.M{}).Skip((page - 1) * 20).Limit(count).Sort("-$natural").All(&addresses)
|
|
check(err)
|
|
|
|
//convert []resp struct to json
|
|
jsonResp, err := json.Marshal(addresses)
|
|
check(err)
|
|
|
|
fmt.Fprintln(w, string(jsonResp))
|
|
}
|
|
func Block(w http.ResponseWriter, r *http.Request) {
|
|
ipFilter(w, r)
|
|
|
|
vars := mux.Vars(r)
|
|
var heightString string
|
|
heightString = vars["height"]
|
|
height, err := strconv.ParseInt(heightString, 10, 64)
|
|
if err != nil {
|
|
fmt.Fprintln(w, "not valid height")
|
|
} else {
|
|
block := BlockModel{}
|
|
err := blockCollection.Find(bson.M{"height": height}).One(&block)
|
|
|
|
txs := []TxModel{}
|
|
err = txCollection.Find(bson.M{"blockheight": heightString}).All(&txs)
|
|
block.Txs = txs
|
|
|
|
//convert []resp struct to json
|
|
jsonResp, err := json.Marshal(block)
|
|
check(err)
|
|
|
|
fmt.Fprintln(w, string(jsonResp))
|
|
}
|
|
}
|
|
func Tx(w http.ResponseWriter, r *http.Request) {
|
|
ipFilter(w, r)
|
|
|
|
vars := mux.Vars(r)
|
|
txid := vars["txid"]
|
|
if txid == "undefined" {
|
|
fmt.Fprintln(w, "not valid txid")
|
|
} else {
|
|
tx := TxModel{}
|
|
err := txCollection.Find(bson.M{"txid": txid}).One(&tx)
|
|
|
|
//convert []resp struct to json
|
|
jsonResp, err := json.Marshal(tx)
|
|
check(err)
|
|
|
|
fmt.Fprintln(w, string(jsonResp))
|
|
}
|
|
}
|
|
func Address(w http.ResponseWriter, r *http.Request) {
|
|
ipFilter(w, r)
|
|
|
|
vars := mux.Vars(r)
|
|
hash := vars["hash"]
|
|
if hash == "undefined" {
|
|
fmt.Fprintln(w, "not valid hash")
|
|
} else {
|
|
address := AddressModel{}
|
|
err := addressCollection.Find(bson.M{"hash": hash}).One(&address)
|
|
|
|
txs := []TxModel{}
|
|
err = txCollection.Find(bson.M{"$or": []bson.M{bson.M{"vin.address": hash}, bson.M{"vout.address": hash}}}).All(&txs)
|
|
address.Txs = txs
|
|
|
|
for _, tx := range address.Txs {
|
|
blocks := []BlockModel{}
|
|
err = blockCollection.Find(bson.M{"hash": tx.BlockHash}).All(&blocks)
|
|
for _, block := range blocks {
|
|
address.Blocks = append(address.Blocks, block)
|
|
}
|
|
}
|
|
|
|
//convert []resp struct to json
|
|
jsonResp, err := json.Marshal(address)
|
|
check(err)
|
|
|
|
fmt.Fprintln(w, string(jsonResp))
|
|
}
|
|
}
|
|
func AddressNetwork(w http.ResponseWriter, r *http.Request) {
|
|
ipFilter(w, r)
|
|
|
|
vars := mux.Vars(r)
|
|
address := vars["address"]
|
|
if address == "undefined" {
|
|
fmt.Fprintln(w, "not valid address")
|
|
} else {
|
|
network := addressTree(address)
|
|
network.Nodes[0].Shape = "triangle"
|
|
|
|
//convert []resp struct to json
|
|
jNetwork, err := json.Marshal(network)
|
|
check(err)
|
|
|
|
fmt.Fprintln(w, string(jNetwork))
|
|
}
|
|
}
|
|
func BlockSankey(w http.ResponseWriter, r *http.Request) {
|
|
ipFilter(w, r)
|
|
vars := mux.Vars(r)
|
|
var heightString string
|
|
heightString = vars["height"]
|
|
height, err := strconv.ParseInt(heightString, 10, 64)
|
|
if err != nil {
|
|
fmt.Fprintln(w, "not valid height")
|
|
} else {
|
|
block := BlockModel{}
|
|
err := blockCollection.Find(bson.M{"height": height}).One(&block)
|
|
|
|
txs := []TxModel{}
|
|
err = txCollection.Find(bson.M{"blockheight": heightString}).All(&txs)
|
|
block.Txs = txs
|
|
|
|
var nodesCount int
|
|
mapNodeK := make(map[string]int)
|
|
var sankey SankeyModel
|
|
for _, tx := range block.Txs {
|
|
var sankeyNodeA SankeyNodeModel
|
|
sankeyNodeA.Node = nodesCount
|
|
mapNodeK["tx"] = nodesCount
|
|
nodesCount++
|
|
sankeyNodeA.Name = "tx"
|
|
sankey.Nodes = append(sankey.Nodes, sankeyNodeA)
|
|
|
|
for _, vin := range tx.Vin {
|
|
var sankeyNode SankeyNodeModel
|
|
sankeyNode.Node = nodesCount
|
|
mapNodeK[vin.Address] = nodesCount
|
|
nodesCount++
|
|
sankeyNode.Name = vin.Address
|
|
sankey.Nodes = append(sankey.Nodes, sankeyNode)
|
|
|
|
var sankeyLink SankeyLinkModel
|
|
sankeyLink.Source = mapNodeK[vin.Address]
|
|
sankeyLink.Target = mapNodeK["tx"]
|
|
sankeyLink.Value = vin.Amount
|
|
fmt.Println(sankeyLink)
|
|
sankey.Links = append(sankey.Links, sankeyLink)
|
|
fmt.Println(sankey.Links)
|
|
}
|
|
|
|
for _, vout := range tx.Vout {
|
|
var sankeyNode SankeyNodeModel
|
|
sankeyNode.Node = nodesCount
|
|
mapNodeK[vout.Address] = nodesCount
|
|
nodesCount++
|
|
sankeyNode.Name = vout.Address
|
|
sankey.Nodes = append(sankey.Nodes, sankeyNode)
|
|
|
|
var sankeyLink SankeyLinkModel
|
|
sankeyLink.Source = mapNodeK["tx"]
|
|
sankeyLink.Target = mapNodeK[vout.Address]
|
|
sankeyLink.Value = vout.Value
|
|
fmt.Println(sankeyLink)
|
|
sankey.Links = append(sankey.Links, sankeyLink)
|
|
}
|
|
|
|
}
|
|
|
|
fmt.Println("Sankey generated")
|
|
fmt.Println(sankey)
|
|
|
|
//convert []resp struct to json
|
|
jsonSankey, err := json.Marshal(sankey)
|
|
check(err)
|
|
|
|
fmt.Fprintln(w, string(jsonSankey))
|
|
}
|
|
}
|
|
func TxSankey(w http.ResponseWriter, r *http.Request) {
|
|
ipFilter(w, r)
|
|
vars := mux.Vars(r)
|
|
txid := vars["txid"]
|
|
if txid == "undefined" {
|
|
fmt.Fprintln(w, "not valid height")
|
|
} else {
|
|
|
|
tx := TxModel{}
|
|
err := txCollection.Find(bson.M{"txid": txid}).One(&tx)
|
|
|
|
var nodesCount int
|
|
mapNodeK := make(map[string]int)
|
|
var sankey SankeyModel
|
|
var sankeyNodeA SankeyNodeModel
|
|
sankeyNodeA.Node = nodesCount
|
|
mapNodeK["tx"] = nodesCount
|
|
nodesCount++
|
|
sankeyNodeA.Name = "tx"
|
|
sankey.Nodes = append(sankey.Nodes, sankeyNodeA)
|
|
|
|
fmt.Println(tx.Vin)
|
|
for _, vin := range tx.Vin {
|
|
var sankeyNode SankeyNodeModel
|
|
sankeyNode.Node = nodesCount
|
|
mapNodeK[vin.Address] = nodesCount
|
|
nodesCount++
|
|
sankeyNode.Name = vin.Address
|
|
sankey.Nodes = append(sankey.Nodes, sankeyNode)
|
|
|
|
var sankeyLink SankeyLinkModel
|
|
sankeyLink.Source = mapNodeK[vin.Address]
|
|
sankeyLink.Target = mapNodeK["tx"]
|
|
sankeyLink.Value = vin.Amount
|
|
sankey.Links = append(sankey.Links, sankeyLink)
|
|
}
|
|
|
|
for _, vout := range tx.Vout {
|
|
var sankeyNode SankeyNodeModel
|
|
sankeyNode.Node = nodesCount
|
|
mapNodeK[vout.Address] = nodesCount
|
|
nodesCount++
|
|
sankeyNode.Name = vout.Address
|
|
sankey.Nodes = append(sankey.Nodes, sankeyNode)
|
|
|
|
var sankeyLink SankeyLinkModel
|
|
sankeyLink.Source = mapNodeK["tx"]
|
|
sankeyLink.Target = mapNodeK[vout.Address]
|
|
sankeyLink.Value = vout.Value
|
|
sankey.Links = append(sankey.Links, sankeyLink)
|
|
}
|
|
|
|
fmt.Println("Sankey generated")
|
|
|
|
//convert []resp struct to json
|
|
jsonSankey, err := json.Marshal(sankey)
|
|
check(err)
|
|
|
|
fmt.Fprintln(w, string(jsonSankey))
|
|
}
|
|
}
|
|
func AddressSankey(w http.ResponseWriter, r *http.Request) {
|
|
ipFilter(w, r)
|
|
vars := mux.Vars(r)
|
|
address := vars["address"]
|
|
if address == "undefined" {
|
|
fmt.Fprintln(w, "not valid address")
|
|
} else {
|
|
network := addressTree(address)
|
|
var sankey SankeyModel
|
|
|
|
fmt.Println("network generated")
|
|
mapNodeK := make(map[string]int)
|
|
for k, n := range network.Nodes {
|
|
var sankeyNode SankeyNodeModel
|
|
//sankeyNode.StringNode = n.Id
|
|
sankeyNode.Node = k
|
|
sankeyNode.Name = n.Id
|
|
sankey.Nodes = append(sankey.Nodes, sankeyNode)
|
|
mapNodeK[n.Id] = k
|
|
}
|
|
for _, e := range network.Edges {
|
|
var sankeyLink SankeyLinkModel
|
|
//sankeyLink.StringSource = e.From
|
|
sankeyLink.Source = mapNodeK[e.From]
|
|
//sankeyLink.StringTarget = e.To
|
|
sankeyLink.Target = mapNodeK[e.To]
|
|
sankeyLink.Value = e.Label
|
|
sankey.Links = append(sankey.Links, sankeyLink)
|
|
}
|
|
fmt.Println("Sankey generated")
|
|
|
|
//convert []resp struct to json
|
|
jsonSankey, err := json.Marshal(sankey)
|
|
check(err)
|
|
|
|
fmt.Fprintln(w, string(jsonSankey))
|
|
}
|
|
}
|
|
func NetworkMap(w http.ResponseWriter, r *http.Request) {
|
|
ipFilter(w, r)
|
|
|
|
nodes, err := getAllNodes()
|
|
check(err)
|
|
edges, err := getAllEdges()
|
|
check(err)
|
|
|
|
var network NetworkModel
|
|
network.Nodes = nodes
|
|
network.Edges = edges
|
|
|
|
//convert []resp struct to json
|
|
jNetwork, err := json.Marshal(network)
|
|
check(err)
|
|
|
|
fmt.Fprintln(w, string(jNetwork))
|
|
}
|
|
|
|
func GetTotalHourAnalysis(w http.ResponseWriter, r *http.Request) {
|
|
ipFilter(w, r)
|
|
|
|
hourAnalysis := []ChartCountModel{}
|
|
iter := hourCountCollection.Find(bson.M{}).Limit(10000).Iter()
|
|
err := iter.All(&hourAnalysis)
|
|
|
|
//sort by hour
|
|
sort.Slice(hourAnalysis, func(i, j int) bool {
|
|
return hourAnalysis[i].Elem < hourAnalysis[j].Elem
|
|
})
|
|
|
|
var resp ChartAnalysisResp
|
|
for _, d := range hourAnalysis {
|
|
resp.Labels = append(resp.Labels, strconv.Itoa(d.Elem))
|
|
resp.Data = append(resp.Data, d.Count)
|
|
}
|
|
|
|
//convert []resp struct to json
|
|
jsonResp, err := json.Marshal(resp)
|
|
check(err)
|
|
fmt.Fprintln(w, string(jsonResp))
|
|
}
|
|
|
|
func GetLast24HourAnalysis(w http.ResponseWriter, r *http.Request) {
|
|
ipFilter(w, r)
|
|
|
|
fromDate := time.Now().AddDate(0, 0, -1)
|
|
toDate := time.Now()
|
|
|
|
txs := []TxModel{}
|
|
err := txCollection.Find(bson.M{
|
|
"datet": bson.M{
|
|
"$gt": fromDate,
|
|
"$lt": toDate,
|
|
},
|
|
}).Sort("-$natural").All(&txs)
|
|
check(err)
|
|
|
|
//generate map with 24 hours
|
|
hourFrequencies := map24hours()
|
|
for _, tx := range txs {
|
|
hourFrequencies[tx.Date.Hour]++
|
|
}
|
|
var hourCount []ChartCountModel
|
|
for hour, frequency := range hourFrequencies {
|
|
hourCount = append(hourCount, ChartCountModel{hour, frequency})
|
|
}
|
|
//sort by hour
|
|
sort.Slice(hourCount, func(i, j int) bool {
|
|
return hourCount[i].Elem < hourCount[j].Elem
|
|
})
|
|
|
|
var resp ChartAnalysisResp
|
|
for _, d := range hourCount {
|
|
resp.Labels = append(resp.Labels, strconv.Itoa(d.Elem))
|
|
resp.Data = append(resp.Data, d.Count)
|
|
}
|
|
|
|
//convert []resp struct to json
|
|
jsonResp, err := json.Marshal(resp)
|
|
check(err)
|
|
fmt.Fprintln(w, string(jsonResp))
|
|
}
|
|
func GetLast7DayAnalysis(w http.ResponseWriter, r *http.Request) {
|
|
ipFilter(w, r)
|
|
|
|
fromDate := time.Now().AddDate(0, 0, -7)
|
|
toDate := time.Now()
|
|
|
|
txs := []TxModel{}
|
|
err := txCollection.Find(bson.M{
|
|
"datet": bson.M{
|
|
"$gt": fromDate,
|
|
"$lt": toDate,
|
|
},
|
|
}).Sort("-$natural").All(&txs)
|
|
check(err)
|
|
|
|
//generate map with 24 hours
|
|
//hourFrequencies := map24hours()
|
|
dayFrequencies := make(map[int]int)
|
|
for _, tx := range txs {
|
|
dayFrequencies[tx.Date.Day]++
|
|
}
|
|
var dayCount []ChartCountModel
|
|
for day, frequency := range dayFrequencies {
|
|
dayCount = append(dayCount, ChartCountModel{day, frequency})
|
|
}
|
|
//sort by hour
|
|
sort.Slice(dayCount, func(i, j int) bool {
|
|
return dayCount[i].Elem < dayCount[j].Elem
|
|
})
|
|
|
|
var resp ChartAnalysisResp
|
|
for _, d := range dayCount {
|
|
resp.Labels = append(resp.Labels, strconv.Itoa(d.Elem))
|
|
resp.Data = append(resp.Data, d.Count)
|
|
}
|
|
|
|
//convert []resp struct to json
|
|
jsonResp, err := json.Marshal(resp)
|
|
check(err)
|
|
fmt.Fprintln(w, string(jsonResp))
|
|
}
|
|
|
|
func GetLast7DayHourAnalysis(w http.ResponseWriter, r *http.Request) {
|
|
ipFilter(w, r)
|
|
|
|
var resp ChartSeriesAnalysisResp
|
|
|
|
for i := 0; i < 7; i++ {
|
|
fromDate := time.Now().AddDate(0, 0, -i-1)
|
|
toDate := time.Now().AddDate(0, 0, -i)
|
|
txs := []TxModel{}
|
|
err := txCollection.Find(bson.M{
|
|
"datet": bson.M{
|
|
"$gt": fromDate,
|
|
"$lt": toDate,
|
|
},
|
|
}).Sort("-$natural").All(&txs)
|
|
check(err)
|
|
|
|
//generate map with 24 hours
|
|
hourFrequencies := map24hours()
|
|
for _, tx := range txs {
|
|
hourFrequencies[tx.Date.Hour]++
|
|
}
|
|
var hourCount []ChartCountModel
|
|
for hour, frequency := range hourFrequencies {
|
|
hourCount = append(hourCount, ChartCountModel{hour, frequency})
|
|
}
|
|
//sort by hour
|
|
sort.Slice(hourCount, func(i, j int) bool {
|
|
return hourCount[i].Elem < hourCount[j].Elem
|
|
})
|
|
var dayData []int
|
|
for _, d := range hourCount {
|
|
dayData = append(dayData, d.Count)
|
|
}
|
|
if len(txs) > 0 {
|
|
resp.Series = append(resp.Series, txs[0].Date.Day)
|
|
resp.Data = append(resp.Data, dayData)
|
|
}
|
|
}
|
|
hourLabels := []string{"0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19", "20", "21", "22", "23"}
|
|
resp.Labels = hourLabels
|
|
|
|
//convert []resp struct to json
|
|
jsonResp, err := json.Marshal(resp)
|
|
check(err)
|
|
fmt.Fprintln(w, string(jsonResp))
|
|
}
|
|
func GetLastMonthsAnalysis(w http.ResponseWriter, r *http.Request) {
|
|
ipFilter(w, r)
|
|
vars := mux.Vars(r)
|
|
count, err := strconv.Atoi(vars["count"])
|
|
check(err)
|
|
fmt.Println(count)
|
|
fromDate := time.Now().AddDate(0, -count, 0)
|
|
toDate := time.Now()
|
|
|
|
txs := []TxModel{}
|
|
err = txCollection.Find(bson.M{
|
|
"datet": bson.M{
|
|
"$gt": fromDate,
|
|
"$lt": toDate,
|
|
},
|
|
}).Sort("-$natural").All(&txs)
|
|
check(err)
|
|
|
|
//generate map with 24 hours
|
|
//hourFrequencies := map24hours()
|
|
dayFrequencies := make(map[float64]int)
|
|
for _, tx := range txs {
|
|
dayFrequencies[float64(tx.Date.Month) + float64(tx.Date.Day)/100]++
|
|
}
|
|
var dayCount []ChartCountFloat64Model
|
|
for day, frequency := range dayFrequencies {
|
|
dayCount = append(dayCount, ChartCountFloat64Model{day, frequency})
|
|
}
|
|
//sort by hour
|
|
sort.Slice(dayCount, func(i, j int) bool {
|
|
return dayCount[i].Elem < dayCount[j].Elem
|
|
})
|
|
|
|
var resp ChartAnalysisResp
|
|
for _, d := range dayCount {
|
|
resp.Labels = append(resp.Labels, strconv.FormatFloat(d.Elem, 'f', -1, 64))
|
|
resp.Data = append(resp.Data, d.Count)
|
|
}
|
|
|
|
//convert []resp struct to json
|
|
jsonResp, err := json.Marshal(resp)
|
|
check(err)
|
|
fmt.Fprintln(w, string(jsonResp))
|
|
}
|
|
func GetAddressTimeChart(w http.ResponseWriter, r *http.Request) {
|
|
ipFilter(w, r)
|
|
|
|
vars := mux.Vars(r)
|
|
hash := vars["hash"]
|
|
if hash == "undefined" {
|
|
fmt.Fprintln(w, "not valid hash")
|
|
} else {
|
|
address := AddressModel{}
|
|
err := addressCollection.Find(bson.M{"hash": hash}).One(&address)
|
|
|
|
txs := []TxModel{}
|
|
err = txCollection.Find(bson.M{"$or": []bson.M{bson.M{"vin.address": hash}, bson.M{"vout.address": hash}}}).All(&txs)
|
|
address.Txs = txs
|
|
|
|
for _, tx := range address.Txs {
|
|
blocks := []BlockModel{}
|
|
err = blockCollection.Find(bson.M{"hash": tx.BlockHash}).All(&blocks)
|
|
for _, block := range blocks {
|
|
address.Blocks = append(address.Blocks, block)
|
|
}
|
|
}
|
|
|
|
count := make(map[time.Time]float64)
|
|
for _, tx := range txs {
|
|
var val float64
|
|
for _, vin := range tx.Vin {
|
|
val = val + vin.Amount
|
|
}
|
|
count[tx.DateT] = val
|
|
}
|
|
var dateSorted []time.Time
|
|
for t, _ := range count {
|
|
dateSorted = append(dateSorted, t)
|
|
}
|
|
sort.Slice(dateSorted, func(i, j int) bool {
|
|
//return dateSorted[i] < dateSorted[j]
|
|
return dateBeforeThan(dateSorted[i], dateSorted[j])
|
|
})
|
|
|
|
var resp ChartAnalysisRespFloat64
|
|
for _, t := range dateSorted {
|
|
resp.Labels = append(resp.Labels, t.String())
|
|
resp.Data = append(resp.Data, count[t])
|
|
}
|
|
|
|
//convert []resp struct to json
|
|
jsonResp, err := json.Marshal(resp)
|
|
check(err)
|
|
|
|
fmt.Fprintln(w, string(jsonResp))
|
|
}
|
|
}
|