Skip to content

Commit

Permalink
Merge pull request #27 from 21Bruce/develop
Browse files Browse the repository at this point in the history
Bug fixes + Early authentication
  • Loading branch information
21Bruce committed Jan 14, 2024
2 parents 7f5db46 + 56e10be commit 60e88dd
Show file tree
Hide file tree
Showing 7 changed files with 183 additions and 217 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
*.swp
*.swo
*.DS_Store
*.exe

30 changes: 23 additions & 7 deletions api/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ package api
import (
"errors"
"strconv"
"time"
)

var (
Expand All @@ -15,6 +16,8 @@ var (
ErrNetwork = errors.New("unknown network error")
ErrPastDate = errors.New("latest reservation time has passed")
ErrTimeNull = errors.New("times list empty")
ErrNoOffer = errors.New("table is not offered on given date")
ErrNoPayInfo = errors.New("no payment info on account")
)

/*
Expand Down Expand Up @@ -96,12 +99,27 @@ type SearchResult struct {
/*
Name: Time
Type: API Input Struct
Purpose: Provide a go indepent struct for representing time
Purpose: Provide a go independent struct for representing time
*/
/*
type Time struct {
CTime time.Time
}
*/

/*
Name: LongTime
Type: API Input Struct
Purpose: Provide a go indepent struct for representing time
at a long scale(i.e. years + months + days)
*/
/*type LongTime struct {
Year string
Month string
Day string
Hour string
Minute string
}
}*/

/*
Name: ReserveParam
Expand All @@ -110,10 +128,7 @@ Purpose: Input information to the 'Reserve' api function
*/
type ReserveParam struct {
VenueID int64
Day string
Month string
Year string
ReservationTimes []Time
ReservationTimes []time.Time
PartySize int
LoginResp LoginResponse
}
Expand All @@ -124,7 +139,7 @@ Type: API Func Output Struct
Purpose: Output information from the 'Reserve' api function
*/
type ReserveResponse struct {
ReservationTime Time
ReservationTime time.Time
}

/*
Expand All @@ -138,6 +153,7 @@ type API interface {
Login(params LoginParam) (*LoginResponse, error)
Search(params SearchParam) (*SearchResponse, error)
Reserve(params ReserveParam) (*ReserveResponse, error)
AuthMinExpire() (time.Duration)
}

/*
Expand Down
10 changes: 10 additions & 0 deletions api/doc.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,5 +56,15 @@ Search:
reservation request.
**********************************************************************
AuthMinExpire:
The AuthMinExpire function provides the minimum time irresepective
of time zone that a login token from the Login function is valid.
This function returns a constant value. If a null value is
returned, the login token is valid indefinitely.
**********************************************************************
*/
package api
48 changes: 43 additions & 5 deletions api/resy/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import (
"bytes"
"strconv"
"strings"
"time"
)

/*
Expand Down Expand Up @@ -124,16 +125,23 @@ func (a *API) Login(params api.LoginParam) (*api.LoginResponse, error) {
defer response.Body.Close()

responseBody, err := io.ReadAll(response.Body)

if err != nil {
return nil, err
}


var jsonMap map[string]interface{}
err = json.Unmarshal(responseBody, &jsonMap)
if err != nil {
return nil, err
}

if jsonMap["payment_method_id"] == nil {
return nil, api.ErrNoPayInfo
}


loginResponse := api.LoginResponse{
ID: int64(jsonMap["id"].(float64)),
FirstName: jsonMap["first_name"].(string),
Expand Down Expand Up @@ -236,7 +244,10 @@ Purpose: Resy implementation of the Reserve api func
func (a *API) Reserve(params api.ReserveParam) (*api.ReserveResponse, error) {

// converting fields to url query format
date := params.Year + "-" + params.Month + "-" + params.Day
year := strconv.Itoa(params.ReservationTimes[0].Year())
month := strconv.Itoa(int(params.ReservationTimes[0].Month()))
day := strconv.Itoa(params.ReservationTimes[0].Day())
date := year + "-" + month + "-" + day
dayField := `day=` + date
authField := `x-resy-auth-token=` + params.LoginResp.AuthToken
latField := `lat=0`
Expand Down Expand Up @@ -282,12 +293,16 @@ func (a *API) Reserve(params api.ReserveParam) (*api.ReserveResponse, error) {
return nil, err
}


// JSON structure is complicated here, see api/resy/doc.go for full explanation
jsonResultsMap := jsonTopLevelMap["results"].(map[string]interface{})
jsonVenuesList := jsonResultsMap["venues"].([]interface{})
jsonVenuesList := jsonResultsMap["venues"].([]interface{})
if len(jsonVenuesList) == 0 {
return nil, api.ErrNoOffer
}
jsonVenueMap := jsonVenuesList[0].(map[string]interface{})
jsonSlotsList := jsonVenueMap["slots"].([]interface{})
for i:=0; i < len(params.ReservationTimes); i++ {
for i := 0; i < len(params.ReservationTimes); i++ {

currentTime := params.ReservationTimes[i]
for j:=0; j < len(jsonSlotsList); j++ {
Expand All @@ -302,8 +317,19 @@ func (a *API) Reserve(params api.ReserveParam) (*api.ReserveResponse, error) {
startFields := strings.Split(startRaw, " ")
// isolate time field and split to get ["HrHr","MnMn"]
timeFields := strings.Split(startFields[1], ":")
// if time field matches of slot matches current selected ResTime, move to config step
if timeFields[0] == currentTime.Hour && timeFields[1] == currentTime.Minute {
// if time field matches of slot matches current selected ResTime, move to config step

hourFieldInt, err := strconv.Atoi(timeFields[0])
if err != nil {
return nil, err
}

minFieldInt, err := strconv.Atoi(timeFields[1])
if err != nil {
return nil, err
}

if hourFieldInt == currentTime.Hour() && minFieldInt == currentTime.Minute() {
jsonConfigMap := jsonSlotMap["config"].(map[string]interface{})
configToken := jsonConfigMap["token"].(string)
configIDField := `config_id=` + url.QueryEscape(configToken)
Expand Down Expand Up @@ -395,6 +421,18 @@ func (a *API) Reserve(params api.ReserveParam) (*api.ReserveResponse, error) {
return nil, api.ErrNoTable
}

/*
Name: AuthMinExpire
Type: API Func
Purpose: Resy implementation of the AuthMinExpire api func.
The largest minimum validity time is 6 days.
*/
func (a *API) AuthMinExpire() (time.Duration) {
/* 6 days */
var d time.Duration = time.Hour * 24 * 6
return d
}

//func (a *API) Cancel(params api.CancelParam) (*api.CancelResponse, error) {
// cancelUrl := `https://api.resy.com/3/cancel`
// resyToken := url.QueryEscape(params.ResyToken)
Expand Down
2 changes: 1 addition & 1 deletion api/resy/doc.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ General Overview of Resy API:
The Search functionality of Resy requires only one request message,
and generally takes a query name as input. On success, we are
given a JSON of restaurant data entries matching the query in
given a JSON of restaurant data entries matching the query in
some way. The specific message structure of a Search operation is
discussed in the 'Search' section of this document.
Expand Down

0 comments on commit 60e88dd

Please sign in to comment.