commands

package
v0.5.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Apr 6, 2021 License: MIT Imports: 12 Imported by: 0

Documentation

Index

Constants

This section is empty.

Variables

View Source
var (
	CommandPublish = &cli.Command{
		Name:  "publish",
		Usage: "start the publisher",
		UsageText: `
Poll the HEB Vaccine location API, pushing locations with vaccines available to a REDIS pub/sub channel

NOTE: The REDIS_HOST_URL environment variable is require. Example: redis://redis.yolo.co:6379
`,
		Flags: []cli.Flag{
			&cli.IntFlag{
				Name:    "delay",
				Aliases: []string{"d"},
				Usage:   "number of seconds to wait between polling",
				Value:   5,
			},
		},
		Action: func(c *cli.Context) error {
			kl := k.Extend("publish")
			delay := c.Int("delay")
			kl.Printf("delay: %d seconds", delay)

			redisHostURL := os.Getenv("REDIS_HOST_URL")
			if redisHostURL == "" {
				return fmt.Errorf("missing REDIS_HOST_URL env variable")
			}
			kl.Println(redisHostURL)
			creds := helpers.ParseRedisURL(redisHostURL)
			kl.Log(creds)
			pool := helpers.NewRedisPool(fmt.Sprintf("%s:%s", creds.Host, creds.Port), creds.User, creds.Password)

			fmt.Printf("[%s] starting\n", time.Now().UTC())
			go helpers.Heartbeat()

			for {
				locations, err := helpers.GetHEBData()
				if err != nil {
					return err
				}

				if len(locations) > 0 {

					kl.Println("publishing")
					for i, location := range locations {
						go func(l *types.Location, c int) {
							conn := pool.Get()
							defer func() {
								if err = conn.Close(); err != nil {
									log.Fatal(err)
								}
							}()
							kl.Printf("%d\tpublishing: %s", c, l.Name)
							if l.Latitude == 0 {
								if tmp, ok := special[l.Name]; ok {
									l.Latitude = tmp.Latitude
									l.Longitude = tmp.Longitude
								} else {
									kl.Printf("\tNo lat/long found for %s", l.Name)
								}
							}

							loc, err := json.Marshal(l)
							if err != nil {
								log.Fatal(err)
								return
							}
							if _, err := conn.Do("PUBLISH", "locations", loc); err != nil {
								log.Fatal(err)
								return
							}
						}(location, i)
					}
				} else {
					kl.Println("No open slots found")
				}

				kl.Printf("-> Checking again in %d seconds ...", delay)
				time.Sleep(time.Duration(delay) * time.Second)
			}
		},
	}
)
View Source
var (
	CommandWatch = &cli.Command{
		Name:    "watch",
		Aliases: []string{"w"},
		Usage:   "start the watcher",
		Flags: []cli.Flag{
			&cli.IntFlag{
				Name:    "miles",
				Aliases: []string{"m"},
				Usage:   "radius in miles from location",
				Value:   30,
			},
			&cli.IntFlag{
				Name:    "delay",
				Aliases: []string{"d"},
				Usage:   "number of seconds to wait between polling",
				Value:   5,
			},
			&cli.Float64Flag{
				Name:    "latitude",
				Aliases: []string{"lat"},
				Usage:   "origin latitude",
				Value:   30.345122515031083,
			},
			&cli.Float64Flag{
				Name:    "longitude",
				Aliases: []string{"lon"},
				Usage:   "origin longitude",
				Value:   -97.96755574412511,
			},
			&cli.IntFlag{
				Name:  "suppress-ttl",
				Usage: "number of minutes to suppress alerting link to previously seen open slots",
				Value: 5,
			},
		},
		Action: func(c *cli.Context) error {
			kl := k.Extend("watch")
			radius := c.Int("miles")
			delay := c.Int("delay")
			suppressTTL := c.Int("suppress-ttl")
			kl.Printf("radius: %d miles -- delay: %d seconds -- ttl: %s", radius, delay, suppressTTL)

			origin := haversine.Coord{Lat: c.Float64("latitude"), Lon: c.Float64("longitude")}

			MCache := mcache.New()

			for {
				locations, err := helpers.GetHEBData()
				if err != nil {
					return err
				}

				if len(locations) > 0 {
					for _, loc := range locations {
						_, ok := MCache.Get(loc.Name)

						var destination haversine.Coord
						var mi float64

						if loc.Latitude != 0 {
							destination = haversine.Coord{Lat: loc.Latitude, Lon: loc.Longitude}
						} else {
							if tmp, ok := special[loc.Name]; ok {
								destination = haversine.Coord{Lat: tmp.Latitude, Lon: tmp.Longitude}
							} else {
								fmt.Printf("\tNo lat/long found for %s\n", loc.Name)
								continue
							}
						}
						mi, _ = haversine.Distance(origin, destination)
						if mi <= float64(radius) {
							fmt.Printf("FOUND %s [%d %s] : %.0f miles", loc.Name, loc.OpenAppointmentSlots, loc.SlotDetails[0].Manufacturer, mi)
							if !ok {
								fmt.Print("\a")
								err := MCache.Set(loc.Name, true, time.Duration(suppressTTL)*time.Minute)
								if err != nil {
									log.Fatal(err)
								}

								fmt.Printf("\nCLICK TO OPEN: %s\n", loc.URL)
								helpers.OpenBrowser(loc.URL)
							} else {
								fmt.Print(" - Already alerting. Silencing for now.")
							}
							fmt.Println("")
						} else {
							fmt.Printf("! %s [%d %s] : %.0f miles\n", loc.Name, loc.OpenAppointmentSlots, loc.SlotDetails[0].Manufacturer, mi)
						}
					}
				} else {
					fmt.Println("No open slots found")
				}

				fmt.Printf("-> Checking again in %d seconds ...", delay)
				time.Sleep(time.Duration(delay) * time.Second)
				fmt.Println("")
			}
		},
	}
)
View Source
var (
	CommandWebsocket = &cli.Command{
		Name:  "websocket",
		Usage: "start the websocket server",
		UsageText: `
Poll the HEB Vaccine location API, pushing locations with vaccines available to a websocket
`,
		Flags: []cli.Flag{
			&cli.IntFlag{
				Name:    "delay",
				Aliases: []string{"d"},
				Usage:   "number of seconds to wait between polling",
				Value:   5,
			},
			&cli.StringFlag{
				Name:    "addr",
				EnvVars: []string{"WEBSOCKET_HOST"},
				Value:   "localhost:8337",
				Usage:   "host address to bind to",
			},
		},
		Action: func(c *cli.Context) error {
			kl := k.Extend("websocket")
			delay := c.Int("delay")
			kl.Printf("delay: %d seconds", delay)

			fmt.Printf("[%s] starting\n", time.Now().UTC())
			go helpers.Heartbeat()

			hub := helpers.NewHub()
			go hub.Run()

			go scrapeHEB(delay, hub)

			http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
				helpers.ServeWs(hub, w, r)
			})
			err := http.ListenAndServe(c.String("addr"), nil)
			if err != nil {
				log.Fatal("ListenAndServe: ", err)
			}
			return nil
		},
	}
)

Functions

This section is empty.

Types

This section is empty.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL