You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

427 lines
9.1 KiB

  1. package main
  2. import (
  3. "encoding/json"
  4. "fmt"
  5. "net/http"
  6. "sort"
  7. "strconv"
  8. "time"
  9. "gopkg.in/mgo.v2/bson"
  10. "github.com/gorilla/mux"
  11. )
  12. type Routes []Route
  13. var routes = Routes{
  14. Route{
  15. "Index",
  16. "GET",
  17. "/",
  18. Index,
  19. },
  20. Route{
  21. "Stats",
  22. "Get",
  23. "/stats",
  24. Stats,
  25. },
  26. Route{
  27. "AllAddresses",
  28. "Get",
  29. "/alladdresses",
  30. AllAddresses,
  31. },
  32. Route{
  33. "GetLastAddr",
  34. "Get",
  35. "/lastaddr",
  36. GetLastAddr,
  37. },
  38. Route{
  39. "GetLastTx",
  40. "Get",
  41. "/lasttx",
  42. GetLastTx,
  43. },
  44. Route{
  45. "AddressNetwork",
  46. "GET",
  47. "/address/network/{address}",
  48. AddressNetwork,
  49. },
  50. Route{
  51. "Address",
  52. "GET",
  53. "/address/{hash}",
  54. Address,
  55. },
  56. Route{
  57. "AddressSankey",
  58. "GET",
  59. "/address/sankey/{address}",
  60. AddressSankey,
  61. },
  62. Route{
  63. "NetworkMap",
  64. "Get",
  65. "/map",
  66. NetworkMap,
  67. },
  68. Route{
  69. "GetTotalHourAnalysis",
  70. "Get",
  71. "/totalhouranalysis",
  72. GetTotalHourAnalysis,
  73. },
  74. Route{
  75. "GetLast24HourAnalysis",
  76. "Get",
  77. "/last24hour",
  78. GetLast24HourAnalysis,
  79. },
  80. Route{
  81. "GetLast7DayAnalysis",
  82. "Get",
  83. "/last7day",
  84. GetLast7DayAnalysis,
  85. },
  86. Route{
  87. "GetLast7DayHourAnalysis",
  88. "Get",
  89. "/last7dayhour",
  90. GetLast7DayHourAnalysis,
  91. },
  92. }
  93. //ROUTES
  94. func Index(w http.ResponseWriter, r *http.Request) {
  95. fmt.Fprintln(w, "ask for recommendations in /r")
  96. //http.FileServer(http.Dir("./web"))
  97. }
  98. /*
  99. func NewUser(w http.ResponseWriter, r *http.Request) {
  100. ipFilter(w, r)
  101. decoder := json.NewDecoder(r.Body)
  102. var newUser UserModel
  103. err := decoder.Decode(&newUser)
  104. check(err)
  105. defer r.Body.Close()
  106. saveUser(userCollection, newUser)
  107. fmt.Println(newUser)
  108. fmt.Fprintln(w, "new user added: ", newUser.ID)
  109. }
  110. */
  111. func Stats(w http.ResponseWriter, r *http.Request) {
  112. ipFilter(w, r)
  113. stats := getStats()
  114. jsonResp, err := json.Marshal(stats)
  115. check(err)
  116. fmt.Fprintln(w, string(jsonResp))
  117. }
  118. func AllAddresses(w http.ResponseWriter, r *http.Request) {
  119. ipFilter(w, r)
  120. nodes := []NodeModel{}
  121. iter := nodeCollection.Find(bson.M{"type": "address"}).Limit(10000).Iter()
  122. err := iter.All(&nodes)
  123. //convert []resp struct to json
  124. jsonNodes, err := json.Marshal(nodes)
  125. check(err)
  126. fmt.Fprintln(w, string(jsonNodes))
  127. }
  128. func GetLastAddr(w http.ResponseWriter, r *http.Request) {
  129. ipFilter(w, r)
  130. addresses := []AddressModel{}
  131. err := addressCollection.Find(bson.M{}).Limit(10).Sort("-$natural").All(&addresses)
  132. check(err)
  133. //convert []resp struct to json
  134. jsonResp, err := json.Marshal(addresses)
  135. check(err)
  136. fmt.Fprintln(w, string(jsonResp))
  137. }
  138. func GetLastTx(w http.ResponseWriter, r *http.Request) {
  139. ipFilter(w, r)
  140. txs := []TxModel{}
  141. err := txCollection.Find(bson.M{}).Limit(10).Sort("-$natural").All(&txs)
  142. check(err)
  143. //convert []resp struct to json
  144. jsonData, err := json.Marshal(txs)
  145. check(err)
  146. fmt.Fprintln(w, string(jsonData))
  147. }
  148. func AddressNetwork(w http.ResponseWriter, r *http.Request) {
  149. ipFilter(w, r)
  150. vars := mux.Vars(r)
  151. address := vars["address"]
  152. if address == "undefined" {
  153. fmt.Fprintln(w, "not valid address")
  154. } else {
  155. network := addressTree(address)
  156. network.Nodes[0].Shape = "triangle"
  157. //convert []resp struct to json
  158. jNetwork, err := json.Marshal(network)
  159. check(err)
  160. fmt.Fprintln(w, string(jNetwork))
  161. }
  162. }
  163. func Address(w http.ResponseWriter, r *http.Request) {
  164. ipFilter(w, r)
  165. vars := mux.Vars(r)
  166. hash := vars["hash"]
  167. if hash == "undefined" {
  168. fmt.Fprintln(w, "not valid hash")
  169. } else {
  170. address := AddressModel{}
  171. err := addressCollection.Find(bson.M{"hash": hash}).One(&address)
  172. txs := []TxModel{}
  173. err = txCollection.Find(bson.M{"$or": []bson.M{bson.M{"from": hash}, bson.M{"to": hash}}}).All(&txs)
  174. address.Txs = txs
  175. for _, tx := range address.Txs {
  176. blocks := []BlockModel{}
  177. err = blockCollection.Find(bson.M{"hash": tx.BlockHash}).All(&blocks)
  178. for _, block := range blocks {
  179. address.Blocks = append(address.Blocks, block)
  180. }
  181. }
  182. //convert []resp struct to json
  183. jsonResp, err := json.Marshal(address)
  184. check(err)
  185. fmt.Fprintln(w, string(jsonResp))
  186. }
  187. }
  188. func AddressSankey(w http.ResponseWriter, r *http.Request) {
  189. ipFilter(w, r)
  190. vars := mux.Vars(r)
  191. address := vars["address"]
  192. if address == "undefined" {
  193. fmt.Fprintln(w, "not valid address")
  194. } else {
  195. network := addressTree(address)
  196. var sankey SankeyModel
  197. fmt.Println("network generated")
  198. mapNodeK := make(map[string]int)
  199. for k, n := range network.Nodes {
  200. var sankeyNode SankeyNodeModel
  201. //sankeyNode.StringNode = n.Id
  202. sankeyNode.Node = k
  203. sankeyNode.Name = n.Id
  204. sankey.Nodes = append(sankey.Nodes, sankeyNode)
  205. mapNodeK[n.Id] = k
  206. }
  207. for _, e := range network.Edges {
  208. var sankeyLink SankeyLinkModel
  209. //sankeyLink.StringSource = e.From
  210. sankeyLink.Source = mapNodeK[e.From]
  211. //sankeyLink.StringTarget = e.To
  212. sankeyLink.Target = mapNodeK[e.To]
  213. sankeyLink.Value = e.Label
  214. sankey.Links = append(sankey.Links, sankeyLink)
  215. }
  216. fmt.Println("Sankey generated")
  217. //convert []resp struct to json
  218. jsonSankey, err := json.Marshal(sankey)
  219. check(err)
  220. fmt.Fprintln(w, string(jsonSankey))
  221. }
  222. }
  223. func NetworkMap(w http.ResponseWriter, r *http.Request) {
  224. ipFilter(w, r)
  225. nodes, err := getAllNodes()
  226. check(err)
  227. edges, err := getAllEdges()
  228. check(err)
  229. var network NetworkModel
  230. network.Nodes = nodes
  231. network.Edges = edges
  232. //convert []resp struct to json
  233. jNetwork, err := json.Marshal(network)
  234. check(err)
  235. fmt.Fprintln(w, string(jNetwork))
  236. }
  237. func GetTotalHourAnalysis(w http.ResponseWriter, r *http.Request) {
  238. ipFilter(w, r)
  239. hourAnalysis := []ChartCountModel{}
  240. iter := hourCountCollection.Find(bson.M{}).Limit(10000).Iter()
  241. err := iter.All(&hourAnalysis)
  242. //sort by hour
  243. sort.Slice(hourAnalysis, func(i, j int) bool {
  244. return hourAnalysis[i].Elem < hourAnalysis[j].Elem
  245. })
  246. var resp ChartAnalysisResp
  247. for _, d := range hourAnalysis {
  248. resp.Labels = append(resp.Labels, strconv.Itoa(d.Elem))
  249. resp.Data = append(resp.Data, d.Count)
  250. }
  251. //convert []resp struct to json
  252. jsonResp, err := json.Marshal(resp)
  253. check(err)
  254. fmt.Fprintln(w, string(jsonResp))
  255. }
  256. func GetLast24HourAnalysis(w http.ResponseWriter, r *http.Request) {
  257. ipFilter(w, r)
  258. fromDate := time.Now().AddDate(0, 0, -1)
  259. toDate := time.Now()
  260. txs := []TxModel{}
  261. err := txCollection.Find(bson.M{
  262. "datet": bson.M{
  263. "$gt": fromDate,
  264. "$lt": toDate,
  265. },
  266. }).Sort("-$natural").All(&txs)
  267. check(err)
  268. //generate map with 24 hours
  269. hourFrequencies := map24hours()
  270. for _, tx := range txs {
  271. hourFrequencies[tx.Date.Hour]++
  272. }
  273. var hourCount []ChartCountModel
  274. for hour, frequency := range hourFrequencies {
  275. hourCount = append(hourCount, ChartCountModel{hour, frequency})
  276. }
  277. //sort by hour
  278. sort.Slice(hourCount, func(i, j int) bool {
  279. return hourCount[i].Elem < hourCount[j].Elem
  280. })
  281. var resp ChartAnalysisResp
  282. for _, d := range hourCount {
  283. resp.Labels = append(resp.Labels, strconv.Itoa(d.Elem))
  284. resp.Data = append(resp.Data, d.Count)
  285. }
  286. //convert []resp struct to json
  287. jsonResp, err := json.Marshal(resp)
  288. check(err)
  289. fmt.Fprintln(w, string(jsonResp))
  290. }
  291. func GetLast7DayAnalysis(w http.ResponseWriter, r *http.Request) {
  292. ipFilter(w, r)
  293. fromDate := time.Now().AddDate(0, 0, -7)
  294. toDate := time.Now()
  295. txs := []TxModel{}
  296. err := txCollection.Find(bson.M{
  297. "datet": bson.M{
  298. "$gt": fromDate,
  299. "$lt": toDate,
  300. },
  301. }).Sort("-$natural").All(&txs)
  302. check(err)
  303. //generate map with 24 hours
  304. //hourFrequencies := map24hours()
  305. dayFrequencies := make(map[int]int)
  306. for _, tx := range txs {
  307. dayFrequencies[tx.Date.Day]++
  308. }
  309. var dayCount []ChartCountModel
  310. for day, frequency := range dayFrequencies {
  311. dayCount = append(dayCount, ChartCountModel{day, frequency})
  312. }
  313. //sort by hour
  314. sort.Slice(dayCount, func(i, j int) bool {
  315. return dayCount[i].Elem < dayCount[j].Elem
  316. })
  317. var resp ChartAnalysisResp
  318. for _, d := range dayCount {
  319. resp.Labels = append(resp.Labels, strconv.Itoa(d.Elem))
  320. resp.Data = append(resp.Data, d.Count)
  321. }
  322. //convert []resp struct to json
  323. jsonResp, err := json.Marshal(resp)
  324. check(err)
  325. fmt.Fprintln(w, string(jsonResp))
  326. }
  327. func GetLast7DayHourAnalysis(w http.ResponseWriter, r *http.Request) {
  328. ipFilter(w, r)
  329. var resp ChartSeriesAnalysisResp
  330. for i := 0; i < 7; i++ {
  331. fromDate := time.Now().AddDate(0, 0, -i-1)
  332. toDate := time.Now().AddDate(0, 0, -i)
  333. txs := []TxModel{}
  334. err := txCollection.Find(bson.M{
  335. "datet": bson.M{
  336. "$gt": fromDate,
  337. "$lt": toDate,
  338. },
  339. }).Sort("-$natural").All(&txs)
  340. check(err)
  341. //generate map with 24 hours
  342. hourFrequencies := map24hours()
  343. for _, tx := range txs {
  344. hourFrequencies[tx.Date.Hour]++
  345. }
  346. var hourCount []ChartCountModel
  347. for hour, frequency := range hourFrequencies {
  348. hourCount = append(hourCount, ChartCountModel{hour, frequency})
  349. }
  350. //sort by hour
  351. sort.Slice(hourCount, func(i, j int) bool {
  352. return hourCount[i].Elem < hourCount[j].Elem
  353. })
  354. var dayData []int
  355. for _, d := range hourCount {
  356. dayData = append(dayData, d.Count)
  357. }
  358. if len(txs) > 0 {
  359. resp.Series = append(resp.Series, txs[0].Date.Day)
  360. resp.Data = append(resp.Data, dayData)
  361. }
  362. }
  363. 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"}
  364. resp.Labels = hourLabels
  365. //convert []resp struct to json
  366. jsonResp, err := json.Marshal(resp)
  367. check(err)
  368. fmt.Fprintln(w, string(jsonResp))
  369. }