download.go 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114
  1. package geolite
  2. import (
  3. "net/http"
  4. "github.com/0xJacky/Nginx-UI/internal/geolite"
  5. "github.com/gin-gonic/gin"
  6. "github.com/gorilla/websocket"
  7. "github.com/uozi-tech/cosy/logger"
  8. )
  9. const (
  10. StatusInfo = "info"
  11. StatusError = "error"
  12. StatusProgress = "progress"
  13. )
  14. type DownloadProgressResp struct {
  15. Status string `json:"status"`
  16. Progress float64 `json:"progress"`
  17. Message string `json:"message"`
  18. }
  19. func DownloadGeoLiteDB(c *gin.Context) {
  20. var upgrader = websocket.Upgrader{
  21. CheckOrigin: func(r *http.Request) bool {
  22. return true
  23. },
  24. }
  25. // Upgrade HTTP to WebSocket
  26. ws, err := upgrader.Upgrade(c.Writer, c.Request, nil)
  27. if err != nil {
  28. logger.Error(err)
  29. return
  30. }
  31. defer ws.Close()
  32. sendMessage := func(status, message string, progress float64) {
  33. if err := ws.WriteJSON(DownloadProgressResp{
  34. Status: status,
  35. Progress: progress,
  36. Message: message,
  37. }); err != nil {
  38. logger.Error("Failed to send WebSocket message:", err)
  39. }
  40. }
  41. // Check if database already exists
  42. if geolite.DBExists() {
  43. sendMessage(StatusInfo, "Database already exists, removing old version...", 0)
  44. // Optionally remove old database here if you want to force re-download
  45. }
  46. sendMessage(StatusInfo, "Starting download...", 0)
  47. // Download progress channel
  48. downloadProgressChan := make(chan float64, 100)
  49. downloadDone := make(chan error, 1)
  50. // Start download in goroutine
  51. go func() {
  52. downloadDone <- geolite.DownloadGeoLiteDB(downloadProgressChan)
  53. }()
  54. // Track download progress (0-50%)
  55. downloadComplete := false
  56. for !downloadComplete {
  57. select {
  58. case progress := <-downloadProgressChan:
  59. // Scale download progress to 0-50%
  60. scaledProgress := progress * 0.5
  61. sendMessage(StatusProgress, "Downloading GeoLite2 database...", scaledProgress)
  62. case err := <-downloadDone:
  63. if err != nil {
  64. sendMessage(StatusError, "Download failed: "+err.Error(), 0)
  65. return
  66. }
  67. downloadComplete = true
  68. sendMessage(StatusInfo, "Download complete", 50)
  69. }
  70. }
  71. sendMessage(StatusInfo, "Decompressing database...", 50)
  72. // Decompress progress channel
  73. decompressProgressChan := make(chan float64, 100)
  74. decompressDone := make(chan error, 1)
  75. // Start decompression in goroutine
  76. go func() {
  77. decompressDone <- geolite.DecompressGeoLiteDB(decompressProgressChan)
  78. }()
  79. // Track decompression progress (50-100%)
  80. decompressComplete := false
  81. for !decompressComplete {
  82. select {
  83. case progress := <-decompressProgressChan:
  84. // Scale decompress progress to 50-100%
  85. scaledProgress := 50 + (progress * 0.5)
  86. sendMessage(StatusProgress, "Decompressing database...", scaledProgress)
  87. case err := <-decompressDone:
  88. if err != nil {
  89. sendMessage(StatusError, "Decompression failed: "+err.Error(), 50)
  90. return
  91. }
  92. decompressComplete = true
  93. sendMessage(StatusInfo, "Database ready", 100)
  94. }
  95. }
  96. sendMessage(StatusInfo, "GeoLite2 database downloaded and installed successfully", 100)
  97. }