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.

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