1
0

main.go 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125
  1. package main
  2. import (
  3. "archive/tar"
  4. "compress/gzip"
  5. "fmt"
  6. "io"
  7. "net/http"
  8. "os"
  9. "path/filepath"
  10. "strings"
  11. )
  12. const (
  13. // MaxMind GeoLite2 databases (free)
  14. cityDBURL = "https://download.maxmind.com/app/geoip_download?edition_id=GeoLite2-City&license_key=YOUR_LICENSE_KEY&suffix=tar.gz"
  15. countryDBURL = "https://download.maxmind.com/app/geoip_download?edition_id=GeoLite2-Country&license_key=YOUR_LICENSE_KEY&suffix=tar.gz"
  16. outputDir = "internal/geolite"
  17. cityDBName = "GeoLite2-City.mmdb"
  18. countryDBName = "GeoLite2-Country.mmdb"
  19. )
  20. func main() {
  21. fmt.Println("MaxMind GeoLite2 Database Downloader")
  22. fmt.Println("====================================")
  23. fmt.Println()
  24. fmt.Println("Note: This script requires a MaxMind license key.")
  25. fmt.Println("You can get a free license key by signing up at:")
  26. fmt.Println("https://www.maxmind.com/en/geolite2/signup")
  27. fmt.Println()
  28. fmt.Println("Alternative: Download manually and place the .mmdb files in internal/geolite/")
  29. fmt.Println()
  30. // Check if license key is provided via environment variable
  31. licenseKey := os.Getenv("MAXMIND_LICENSE_KEY")
  32. if licenseKey == "" {
  33. fmt.Println("MAXMIND_LICENSE_KEY environment variable not set.")
  34. fmt.Println("Usage: MAXMIND_LICENSE_KEY=your_key go run cmd/geolite_downloader/main.go")
  35. fmt.Println()
  36. fmt.Println("For manual download:")
  37. fmt.Printf("1. Download GeoLite2-City.mmdb to %s/\n", outputDir)
  38. fmt.Printf("2. Download GeoLite2-Country.mmdb to %s/\n", outputDir)
  39. return
  40. }
  41. // Create output directory
  42. if err := os.MkdirAll(outputDir, 0755); err != nil {
  43. fmt.Printf("Failed to create output directory: %v\n", err)
  44. return
  45. }
  46. // Download databases
  47. fmt.Println("Downloading GeoLite2 databases...")
  48. if err := downloadDatabase(strings.Replace(countryDBURL, "YOUR_LICENSE_KEY", licenseKey, 1),
  49. filepath.Join(outputDir, countryDBName)); err != nil {
  50. fmt.Printf("Failed to download Country database: %v\n", err)
  51. } else {
  52. fmt.Printf("✓ Downloaded %s\n", countryDBName)
  53. }
  54. if err := downloadDatabase(strings.Replace(cityDBURL, "YOUR_LICENSE_KEY", licenseKey, 1),
  55. filepath.Join(outputDir, cityDBName)); err != nil {
  56. fmt.Printf("Failed to download City database: %v\n", err)
  57. } else {
  58. fmt.Printf("✓ Downloaded %s\n", cityDBName)
  59. }
  60. fmt.Println()
  61. fmt.Println("Download completed!")
  62. }
  63. func downloadDatabase(url, outputPath string) error {
  64. // Download the tar.gz file
  65. resp, err := http.Get(url)
  66. if err != nil {
  67. return fmt.Errorf("failed to download: %w", err)
  68. }
  69. defer resp.Body.Close()
  70. if resp.StatusCode != http.StatusOK {
  71. return fmt.Errorf("download failed with status: %s", resp.Status)
  72. }
  73. // Create a gzip reader
  74. gzReader, err := gzip.NewReader(resp.Body)
  75. if err != nil {
  76. return fmt.Errorf("failed to create gzip reader: %w", err)
  77. }
  78. defer gzReader.Close()
  79. // Create a tar reader
  80. tarReader := tar.NewReader(gzReader)
  81. // Extract the .mmdb file
  82. for {
  83. header, err := tarReader.Next()
  84. if err == io.EOF {
  85. break
  86. }
  87. if err != nil {
  88. return fmt.Errorf("failed to read tar: %w", err)
  89. }
  90. // Look for .mmdb file
  91. if strings.HasSuffix(header.Name, ".mmdb") {
  92. // Create output file
  93. outFile, err := os.Create(outputPath)
  94. if err != nil {
  95. return fmt.Errorf("failed to create output file: %w", err)
  96. }
  97. defer outFile.Close()
  98. // Copy the file content
  99. _, err = io.Copy(outFile, tarReader)
  100. if err != nil {
  101. return fmt.Errorf("failed to extract file: %w", err)
  102. }
  103. return nil
  104. }
  105. }
  106. return fmt.Errorf("no .mmdb file found in archive")
  107. }