Skip to content

Commit

Permalink
using cobra cli and raw binary
Browse files Browse the repository at this point in the history
  • Loading branch information
Arun Gopalpuri committed Aug 1, 2024
1 parent 5aa2343 commit a039761
Show file tree
Hide file tree
Showing 5 changed files with 98 additions and 55 deletions.
7 changes: 1 addition & 6 deletions .goreleaser.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,8 @@ builds:
binary: global-entry-slot-notifier

archives:
- format: tar.gz
- format: binary
name_template: "{{ .ProjectName }}_{{ .Version }}_{{ .Os }}_{{ .Arch }}"
files:
- LICENSE

checksum:
name_template: "{{ .ProjectName }}_checksums.txt"

changelog:
sort: asc
Expand Down
27 changes: 14 additions & 13 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,9 @@
<p align="center">
<img src="./globalentry.png" width="80" alt="Global Entry"/><img src="./globalentry.png" width="80" alt="Global Entry"/><img src="./globalentry.png" width="80" alt="Global Entry"/>
</p>

Global Entry Slot Notifier is a command-line tool that checks for available Global Entry appointment slots at specified locations
and sends notifications via native system notification or to [ntfy app](https://ntfy.sh/) (available on Android, iPhone, and Mac).
and sends notifications via native system notification or to [ntfy app](https://ntfy.sh/), available on Android, iPhone, and Mac.

## Features

Expand All @@ -20,34 +21,35 @@ and sends notifications via native system notification or to [ntfy app](https://
make all
```

2. Or Download the latest binary zip from the [releases](https://github.com/arun0009/global-entry-slot-notifier/releases) page.
2. Or Download the latest binary from the [releases](https://github.com/arun0009/global-entry-slot-notifier/releases) page
as `global-entry-slot-notifier` (with `.exe` extension for windows)

Extract the tar file and run `global-entry-slot-notifier` binary file. You may need to grant permission to run the binary.
Note: You may need to grant permission to run the binary.

### Usage

```bash
./global-entry-slot-notifier --location <location_id> --notifier <notifier_type> [--topic <ntfy_topic>] [--interval <duration>]
./global-entry-slot-notifier -l <location_id> -n <notifier_type> [-t <ntfy_topic>] [-i <duration>]
```

### Flags
* `--location` (required): Specify the location ID for the Global Entry appointment (see below location ids).
* `--notifier` (required): Specify the notifier type (app or system).
* `--topic` (required if notifier is app): Specify the ntfy.sh [topic](https://docs.ntfy.sh/) to send notifications to.
* `--interval` (optional): Specify the interval (in seconds, e.g. 30s) at which to check for available appointments. Default is 60s.
* `-l`, `--location` (required): Specify the location ID for the Global Entry appointment (see below location ids).
* `-n`, `--notifier` (required): Specify the notifier type (app or system).
* `-t`, `--topic` (required if notifier is app): Specify the ntfy.sh [topic](https://docs.ntfy.sh/) to send notifications to.
* `-i`, `--interval` (optional): Specify the interval (in seconds, e.g. 30s) at which to check for available appointments. Default is 60s.

### Examples

1. System Notification

```bash
./global-entry-slot-notifier --location 5446 --notifier system --interval 90s
./global-entry-slot-notifier -l 5446 -n system -i 90s
```

2. App Notification (first create your [topic on ntfy app](https://docs.ntfy.sh/))

```bash
./global-entry-slot-notifier --location 5446 --notifier app --topic my-ntfy-topic
./global-entry-slot-notifier -l 5446 -n app -t my-ntfy-topic
```

###### Pick your location id from below to use in flag (above)
Expand Down Expand Up @@ -186,9 +188,8 @@ You can download the binary on [raspberry pi](https://www.raspberrypi.com/) or o
and run it as background process to notify you via [ntfy.sh](https://ntfy.sh/))

```bash
curl -L https://github.com/arun0009/global-entry-slot-notifier/releases/download/v1.0/global-entry-slot-notifier_1.0_linux_amd64.tar.gz -o global-entry-slot-notifier.tar.gz
tar -xvf global-entry-slot-notifier.tar.gz global-entry-slot-notifier
./global-entry-slot-notifier --location 5446 --notifier app --topic my-ntfy-topic &
curl -L https://github.com/arun0009/global-entry-slot-notifier/releases/download/v1.0/global-entry-slot-notifier_1.0_linux_amd64 -o global-entry-slot-notifier
./global-entry-slot-notifier -l 5446 -n app -t my-ntfy-topic &
```

### License
Expand Down
102 changes: 67 additions & 35 deletions cmd/main.go
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
package main

import (
"bufio"
"encoding/json"
"flag"
"fmt"
"github.com/gen2brain/beeep"
"github.com/spf13/cobra"
"io"
"log"
"net/http"
Expand Down Expand Up @@ -97,42 +98,73 @@ func appointmentCheck(url string, client HTTPClient, notifier Notifier, topic st
}

func main() {
// Define command-line flags
location := flag.String("location", "", "Specify the location ID")
notifierType := flag.String("notifier", "", "Specify the notifier type (app/system)")
topic := flag.String("topic", "", "Specify the ntfy topic (required if notifier is app)")
interval := flag.Duration("interval", time.Second*60, "Specify the interval")

// Parse command-line flags
flag.Parse()

// Validate flags
if *location == "" || *notifierType == "" || (*notifierType == "app" && *topic == "") {
fmt.Println("Both --location and --notifier flags are required. If notifier is app, --topic is required.")
flag.Usage()
os.Exit(1)
var location string
var notifierType string
var topic string
var interval time.Duration

rootCmd := &cobra.Command{
Use: "global-entry-slot-notifier",
Short: "Checks for appointment slots and sends notifications",
Run: func(cmd *cobra.Command, args []string) {
// Function to prompt user for input
getInput := func(prompt string) string {
reader := bufio.NewReader(os.Stdin)
fmt.Print(prompt)
input, _ := reader.ReadString('\n')
return strings.TrimSpace(input)
}

// Check and prompt for missing flags
if location == "" {
location = getInput("Enter the location ID: ")
}
if notifierType == "" {
notifierType = getInput("Enter the notifier type (app/system): ")
}
if notifierType == "app" && topic == "" {
topic = getInput("Enter the ntfy topic: ")
}

// Validate flags
if location == "" || notifierType == "" || (notifierType == "app" && topic == "") {
fmt.Println("Both --location and --notifier flags are required. If notifier is app, --topic is required.")
_ = cmd.Usage()
os.Exit(1)
}

url := fmt.Sprintf(GlobalEntryUrl, location)

var notifier Notifier
client := &http.Client{}
switch notifierType {
case "app":
notifier = AppNotifier{Client: client}
case "system":
notifier = SystemNotifier{}
default:
log.Fatalf("Unknown notifier type: %s", notifierType)
}

// Create a closure that captures the arguments and calls appointmentCheck with them.
appointmentCheckFunc := func() {
appointmentCheck(url, client, notifier, topic)
}

go appointmentCheckScheduler(interval, appointmentCheckFunc)

// Keep the main function running to allow the ticker to tick.
select {}
},
}

url := fmt.Sprintf(GlobalEntryUrl, *location)

var notifier Notifier
client := &http.Client{}
switch *notifierType {
case "app":
notifier = AppNotifier{Client: client}
case "system":
notifier = SystemNotifier{}
default:
log.Fatalf("Unknown notifier type: %s", *notifierType)
}
rootCmd.Flags().StringVarP(&location, "location", "l", "", "Specify the location ID")
rootCmd.Flags().StringVarP(&notifierType, "notifier", "n", "", "Specify the notifier type (app or system)")
rootCmd.Flags().StringVarP(&topic, "topic", "t", "", "Specify the ntfy topic (required if notifier is app)")
rootCmd.Flags().DurationVarP(&interval, "interval", "i", time.Second*60, "Specify the interval")

// Create a closure that captures the arguments and calls appointmentCheck with them.
appointmentCheckFunc := func() {
appointmentCheck(url, client, notifier, *topic)
if err := rootCmd.Execute(); err != nil {
fmt.Println(err)
os.Exit(1)
}

go appointmentCheckScheduler(*interval, appointmentCheckFunc)

// Keep the main function running to allow the ticker to tick.
select {}
}
7 changes: 6 additions & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,17 @@ module github.com/arun0009/global-entry-slot-notifier

go 1.22

require github.com/gen2brain/beeep v0.0.0-20240516210008-9c006672e7f4
require (
github.com/gen2brain/beeep v0.0.0-20240516210008-9c006672e7f4
github.com/spf13/cobra v1.8.1
)

require (
github.com/go-toast/toast v0.0.0-20190211030409-01e6764cf0a4 // indirect
github.com/godbus/dbus/v5 v5.1.0 // indirect
github.com/inconshreveable/mousetrap v1.1.0 // indirect
github.com/nu7hatch/gouuid v0.0.0-20131221200532-179d4d0c4d8d // indirect
github.com/spf13/pflag v1.0.5 // indirect
github.com/tadvi/systray v0.0.0-20190226123456-11a2b8fa57af // indirect
golang.org/x/sys v0.22.0 // indirect
)
10 changes: 10 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
@@ -1,13 +1,23 @@
github.com/cpuguy83/go-md2man/v2 v2.0.4/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
github.com/gen2brain/beeep v0.0.0-20240516210008-9c006672e7f4 h1:ygs9POGDQpQGLJPlq4+0LBUmMBNox1N4JSpw+OETcvI=
github.com/gen2brain/beeep v0.0.0-20240516210008-9c006672e7f4/go.mod h1:0W7dI87PvXJ1Sjs0QPvWXKcQmNERY77e8l7GFhZB/s4=
github.com/go-toast/toast v0.0.0-20190211030409-01e6764cf0a4 h1:qZNfIGkIANxGv/OqtnntR4DfOY2+BgwR60cAcu/i3SE=
github.com/go-toast/toast v0.0.0-20190211030409-01e6764cf0a4/go.mod h1:kW3HQ4UdaAyrUCSSDR4xUzBKW6O2iA4uHhk7AtyYp10=
github.com/godbus/dbus/v5 v5.1.0 h1:4KLkAxT3aOY8Li4FRJe/KvhoNFFxo0m6fNuFUO8QJUk=
github.com/godbus/dbus/v5 v5.1.0/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
github.com/nu7hatch/gouuid v0.0.0-20131221200532-179d4d0c4d8d h1:VhgPp6v9qf9Agr/56bj7Y/xa04UccTW04VP0Qed4vnQ=
github.com/nu7hatch/gouuid v0.0.0-20131221200532-179d4d0c4d8d/go.mod h1:YUTz3bUH2ZwIWBy3CJBeOBEugqcmXREj14T+iG/4k4U=
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
github.com/spf13/cobra v1.8.1 h1:e5/vxKd/rZsfSJMUX1agtjeTDf+qv1/JdBF8gg5k9ZM=
github.com/spf13/cobra v1.8.1/go.mod h1:wHxEcudfqmLYa8iTfL+OuZPbBZkmvliBWKIezN3kD9Y=
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
github.com/tadvi/systray v0.0.0-20190226123456-11a2b8fa57af h1:6yITBqGTE2lEeTPG04SN9W+iWHCRyHqlVYILiSXziwk=
github.com/tadvi/systray v0.0.0-20190226123456-11a2b8fa57af/go.mod h1:4F09kP5F+am0jAwlQLddpoMDM+iewkxxt6nxUQ5nq5o=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.22.0 h1:RI27ohtqKCnwULzJLqkv897zojh5/DwS/ENaMzUOaWI=
golang.org/x/sys v0.22.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=

0 comments on commit a039761

Please sign in to comment.