Skip to content

Commit

Permalink
refactor: rewrite logic using update libraries
Browse files Browse the repository at this point in the history
  • Loading branch information
noandrea committed Jun 16, 2024
1 parent 39ae479 commit 555db43
Show file tree
Hide file tree
Showing 16 changed files with 671 additions and 339 deletions.
135 changes: 90 additions & 45 deletions cmd/build.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,75 +17,120 @@ package cmd

import (
"fmt"
"os"
"net/http"
"strings"
"time"

"github.com/evanoberholster/timezoneLookup"
"github.com/evanoberholster/timezoneLookup/v2"
"github.com/noandrea/geo2tz/v2/helpers"
"github.com/noandrea/geo2tz/v2/web"
"github.com/spf13/cobra"
)

// buildCmd represents the build command
var buildCmd = &cobra.Command{
Use: "build",
Short: "Build the location database",
Long: `The commands replicates the functionality of the evanoberholster/timezoneLookup timezone command`,
Run: build,
}
const (
// geo data url
LatestReleaseURL = "https://github.com/evansiroky/timezone-boundary-builder/releases/latest"
TZZipFile = "tzdata/timezone.zip"
)

var (
// geo data url
GeoDataURL = "https://github.com/evansiroky/timezone-boundary-builder/releases/download/2022b/timezones-with-oceans.geojson.zip"
// cli parameters.
snappy bool
jsonFilename string
dbFilename string
cacheFile string
geoDataURL string
)

// buildCmd represents the build command
var buildCmd = &cobra.Command{
Use: "build",
Short: "Build the location database for a specific version",
Example: `geo2tz build 2023d`,
Long: `The commands replicates the functionality of the evanoberholster/timezoneLookup timezone command`,
Args: cobra.ExactArgs(1),
RunE: func(cmd *cobra.Command, args []string) error {
tzVersion := web.NewTzRelease(args[0])
return update(tzVersion, cacheFile, web.Settings.Tz.DatabaseName)
},
}

// buildCmd represents the build command
var updateCmd = &cobra.Command{
Use: "update",
Short: "Update the location database by downloading the latest version",
RunE: func(cmd *cobra.Command, args []string) error {
tzVersion, err := getLatest()
if err != nil {
return err
}
return update(tzVersion, cacheFile, web.Settings.Tz.DatabaseName)
},
}

func init() {
rootCmd.AddCommand(buildCmd)
buildCmd.Flags().StringVar(&dbFilename, "db", "timezone", "Destination database filename")
buildCmd.Flags().BoolVar(&snappy, "snappy", true, "Use Snappy compression (true/false)")
buildCmd.Flags().StringVar(&jsonFilename, "json", "combined-with-oceans.json", "GEOJSON Filename")
buildCmd.Flags().StringVar(&cacheFile, "cache", TZZipFile, "Temporary cache filename")
buildCmd.Flags().StringVar(&web.Settings.Tz.DatabaseName, "db", web.TZDBFile, "Destination database filename")
buildCmd.Flags().StringVar(&web.Settings.Tz.VersionFile, "version-file", web.TZVersionFile, "Version file")
rootCmd.AddCommand(updateCmd)
updateCmd.Flags().StringVar(&geoDataURL, "geo-data-url", "", "URL to download geo data from")
updateCmd.Flags().StringVar(&cacheFile, "cache", TZZipFile, "Temporary cache filename")
updateCmd.Flags().StringVar(&web.Settings.Tz.DatabaseName, "db", web.TZDBFile, "Destination database filename")
updateCmd.Flags().StringVar(&web.Settings.Tz.VersionFile, "version-file", web.TZVersionFile, "Version file")
}

func build(*cobra.Command, []string) {
if dbFilename == "" || jsonFilename == "" {
fmt.Printf(`Options:
-snappy=true Use Snappy compression
-json=filename GEOJSON filename
-db=filename Database destination
`)
func update(release web.TzRelease, zipFile, dbFile string) (err error) {
// remove old file
if err = helpers.DeleteQuietly(zipFile, dbFile); err != nil {
return
}

tz := timezoneLookup.MemoryStorage(snappy, dbFilename)

if !fileExists(jsonFilename) {
fmt.Printf("json file %v does not exists, will try to download from the source", jsonFilename)
var (
tzc timezoneLookup.Timezonecache
total int
)
fmt.Printf("building database %s v%s from %s\n", dbFile, release.Version, release.GeoDataURL)
if err = timezoneLookup.ImportZipFile(zipFile, release.GeoDataURL, func(tz timezoneLookup.Timezone) error {
total += len(tz.Polygons)
tzc.AddTimezone(tz)
return nil
}); err != nil {
return
}

if jsonFilename != "" {
err := tz.CreateTimezones(jsonFilename)
if err != nil {
fmt.Println(err)
return
}
} else {
fmt.Println(`"--json" No GeoJSON source file specified`)
if err = tzc.Save(dbFile); err != nil {
return
}
tzc.Close()
fmt.Println("polygons added:", total)
fmt.Println("saved timezone data to:", dbFile)

tz.Close()

// remove tmp file
if err = helpers.DeleteQuietly(cacheFile); err != nil {
return
}
err = helpers.SaveJSON(release, web.Settings.Tz.VersionFile)
return
}

func fileExists(filePath string) bool {
f, err := os.Stat(filePath)
func getLatest() (web.TzRelease, error) {
// create http client
client := &http.Client{
Timeout: 1 * time.Second,
CheckRedirect: func(req *http.Request, via []*http.Request) error {
// don't follow redirects
return http.ErrUseLastResponse
},
}
r, err := client.Head(LatestReleaseURL)
if err != nil {
return false
err = fmt.Errorf("failed to get release url: %w", err)
return web.TzRelease{}, err
}
if f.IsDir() {
return false
defer r.Body.Close()
// get the tag name
releaseURL, err := r.Location()
if err != nil {
err = fmt.Errorf("failed to get release url: %w", err)
return web.TzRelease{}, err
}
return true
v := web.NewTzRelease(releaseURL.Path[strings.LastIndex(releaseURL.Path, "/")+1:])
return v, nil
}
7 changes: 3 additions & 4 deletions cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,14 @@ import (
"log"
"strings"

"github.com/noandrea/geo2tz/v2/web"
"github.com/spf13/cobra"
"github.com/spf13/viper"

"github.com/noandrea/geo2tz/v2/server"
)

var cfgFile string
var debug bool
var settings server.ConfigSchema
var settings web.ConfigSchema

// rootCmd represents the base command when called without any subcommands.
var rootCmd = &cobra.Command{
Expand Down Expand Up @@ -50,7 +49,7 @@ func initConfig() error {
viper.AddConfigPath("/etc/geo2tz")
viper.SetConfigName("config")
}
server.Defaults()
web.Defaults()
viper.SetEnvPrefix("GEO2TZ")
viper.SetEnvKeyReplacer(strings.NewReplacer(".", "_"))
viper.AutomaticEnv() // read in environment variables that match
Expand Down
13 changes: 9 additions & 4 deletions cmd/start.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import (

"github.com/spf13/cobra"

"github.com/noandrea/geo2tz/v2/server"
"github.com/noandrea/geo2tz/v2/web"
)

// startCmd represents the start command.
Expand All @@ -33,10 +33,15 @@ func start(*cobra.Command, []string) {
\_____|\___|\___/____|\__/___| version %s
`, rootCmd.Version)
// Start server
server, err := web.NewServer(settings)
if err != nil {
log.Println("Error creating the server ", err)
os.Exit(1)
}
go func() {
if err := server.Start(settings); err != nil {
if err = server.Start(); err != nil {
log.Println("Error starting the server ", err)
return
os.Exit(1)
}
}()

Expand All @@ -46,7 +51,7 @@ func start(*cobra.Command, []string) {
quit := make(chan os.Signal, signalChannelLength)
signal.Notify(quit, os.Interrupt)
<-quit
if err := server.Teardown(); err != nil {
if err = server.Teardown(); err != nil {
log.Println("error stopping server: ", err)
}
fmt.Print("Goodbye")
Expand Down
42 changes: 42 additions & 0 deletions coverage.out
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
mode: atomic
github.com/noandrea/geo2tz/v2/web/config.go:39.17,47.2 5 0
github.com/noandrea/geo2tz/v2/web/config.go:50.46,53.2 1 0
github.com/noandrea/geo2tz/v2/web/server.go:30.39,33.2 2 7
github.com/noandrea/geo2tz/v2/web/server.go:36.62,38.2 1 2
github.com/noandrea/geo2tz/v2/web/server.go:49.37,51.2 1 0
github.com/noandrea/geo2tz/v2/web/server.go:53.46,57.24 4 0
github.com/noandrea/geo2tz/v2/web/server.go:57.24,59.3 1 0
github.com/noandrea/geo2tz/v2/web/server.go:60.2,60.8 1 0
github.com/noandrea/geo2tz/v2/web/server.go:63.54,69.16 5 4
github.com/noandrea/geo2tz/v2/web/server.go:69.16,72.3 2 1
github.com/noandrea/geo2tz/v2/web/server.go:73.2,75.43 2 3
github.com/noandrea/geo2tz/v2/web/server.go:75.43,78.3 2 0
github.com/noandrea/geo2tz/v2/web/server.go:81.2,82.40 2 3
github.com/noandrea/geo2tz/v2/web/server.go:82.40,85.3 2 0
github.com/noandrea/geo2tz/v2/web/server.go:85.8,87.3 1 3
github.com/noandrea/geo2tz/v2/web/server.go:89.2,96.16 6 3
github.com/noandrea/geo2tz/v2/web/server.go:96.16,99.3 2 1
github.com/noandrea/geo2tz/v2/web/server.go:100.2,101.68 2 2
github.com/noandrea/geo2tz/v2/web/server.go:101.68,104.3 2 0
github.com/noandrea/geo2tz/v2/web/server.go:107.2,110.21 3 2
github.com/noandrea/geo2tz/v2/web/server.go:113.61,115.24 1 4
github.com/noandrea/geo2tz/v2/web/server.go:115.24,117.50 2 0
github.com/noandrea/geo2tz/v2/web/server.go:117.50,120.4 2 0
github.com/noandrea/geo2tz/v2/web/server.go:123.2,124.16 2 4
github.com/noandrea/geo2tz/v2/web/server.go:124.16,127.3 2 2
github.com/noandrea/geo2tz/v2/web/server.go:129.2,130.16 2 2
github.com/noandrea/geo2tz/v2/web/server.go:130.16,133.3 2 1
github.com/noandrea/geo2tz/v2/web/server.go:136.2,137.16 2 1
github.com/noandrea/geo2tz/v2/web/server.go:137.16,140.3 2 0
github.com/noandrea/geo2tz/v2/web/server.go:141.2,141.97 1 1
github.com/noandrea/geo2tz/v2/web/server.go:144.61,146.2 1 1
github.com/noandrea/geo2tz/v2/web/server.go:149.57,150.34 1 19
github.com/noandrea/geo2tz/v2/web/server.go:150.34,152.3 1 2
github.com/noandrea/geo2tz/v2/web/server.go:153.2,154.16 2 17
github.com/noandrea/geo2tz/v2/web/server.go:154.16,156.3 1 2
github.com/noandrea/geo2tz/v2/web/server.go:157.2,157.14 1 15
github.com/noandrea/geo2tz/v2/web/server.go:158.16,159.24 1 8
github.com/noandrea/geo2tz/v2/web/server.go:159.24,161.4 1 4
github.com/noandrea/geo2tz/v2/web/server.go:162.17,163.26 1 7
github.com/noandrea/geo2tz/v2/web/server.go:163.26,165.4 1 4
github.com/noandrea/geo2tz/v2/web/server.go:167.2,167.15 1 7
56 changes: 56 additions & 0 deletions helpers/helpers.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
package helpers

import (
"encoding/json"
"fmt"
"os"
)

func SaveJSON(data any, toFile string) (err error) {
// write the version file as json, overwriting the old one
jsonString, err := json.MarshalIndent(data, "", " ")
if err != nil {
return
}
if err = os.WriteFile(toFile, jsonString, os.ModePerm); err != nil {
return
}
return
}

func LoadJSON(fromFile string, data any) (err error) {
// read the version file
jsonFile, err := os.Open(fromFile)
if err != nil {
return
}
defer jsonFile.Close()
jsonParser := json.NewDecoder(jsonFile)
if err = jsonParser.Decode(data); err != nil {
return
}
return
}

func DeleteQuietly(filePath ...string) (err error) {
for _, filePath := range filePath {
if xErr := FileExists(filePath); xErr == nil {
fmt.Println("removing file", filePath)
if err = os.Remove(filePath); err != nil {
return
}
}
}
return
}

func FileExists(filePath string) error {
f, err := os.Stat(filePath)
if err != nil {
return fmt.Errorf("file does not exist: %s", filePath)
}
if f.IsDir() {
return fmt.Errorf("file is a directory: %s", filePath)
}
return nil
}
10 changes: 7 additions & 3 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,12 +29,16 @@ import (
)

// Version hold the version of the program.
var Version = "0.0.0"
var (
version = "dev"
commit = "unknown"
date = "unknown"
builtBy = "unknown"
)

func main() {
if err := cmd.Execute(Version); err != nil {
if err := cmd.Execute(version); err != nil {
fmt.Println(err)
os.Exit(1)
}

}
16 changes: 0 additions & 16 deletions scripts/update-tzdata.sh

This file was deleted.

Loading

0 comments on commit 555db43

Please sign in to comment.