Skip to content

Commit 9c42cdb

Browse files
api get venue endpoint
1 parent 6a03562 commit 9c42cdb

File tree

5 files changed

+207
-3
lines changed

5 files changed

+207
-3
lines changed

api/api_image_helper.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,10 @@ func IsVenueImageIdentifier(identifier string) bool {
4040
"dark_theme_logo": 2,
4141
"light_theme_logo": 3,
4242
"avatar": 4,
43+
"main_photo": 5,
44+
"gallery_photo_1": 6,
45+
"gallery_photo_2": 7,
46+
"gallery_photo_3": 8,
4347
}
4448

4549
_, ok := mapping[identifier]

api/get_venue.go

Lines changed: 131 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,131 @@
1+
package api
2+
3+
import (
4+
"encoding/json"
5+
"net/http"
6+
7+
"github.com/gin-gonic/gin"
8+
"github.com/sndcds/grains/grains_api"
9+
"github.com/sndcds/uranus/app"
10+
)
11+
12+
// GetVenue returns a venue by Id with spaces and organization
13+
func (h *ApiHandler) GetVenue(gc *gin.Context) {
14+
ctx := gc.Request.Context()
15+
apiRequest := grains_api.NewRequest(gc, "ger-venue")
16+
17+
// Structs for nested data
18+
type SpaceResult struct {
19+
Id int `json:"id"`
20+
Name *string `json:"name,omitempty"`
21+
TotalCapacity *int `json:"total_capacity,omitempty"`
22+
SeatingCapacity *int `json:"seating_capacity,omitempty"`
23+
BuildingLevel *int `json:"building_level,omitempty"`
24+
WebsiteLink *string `json:"website_link,omitempty"`
25+
Description *string `json:"description,omitempty"`
26+
AreaSqm *float64 `json:"area_sqm,omitempty"`
27+
SpaceType *string `json:"space_type,omitempty"`
28+
SpaceTypeName *string `json:"space_type_name,omitempty"`
29+
SpaceTypeDesc *string `json:"space_type_description,omitempty"`
30+
}
31+
32+
type OrganizationResult struct {
33+
Id int `json:"id"`
34+
Name *string `json:"name,omitempty"`
35+
WebsiteLink *string `json:"website_link,omitempty"`
36+
City *string `json:"city,omitempty"`
37+
Country *string `json:"country,omitempty"`
38+
}
39+
40+
type VenueResult struct {
41+
Id int `json:"id"`
42+
Name *string `json:"name,omitempty"`
43+
Type *string `json:"type,omitempty"`
44+
TypeName *string `json:"type_name,omitempty"`
45+
TypeDescription *string `json:"type_description,omitempty"`
46+
OpenedAt *string `json:"opened_at,omitempty"`
47+
ClosedAt *string `json:"closed_at,omitempty"`
48+
Description *string `json:"description,omitempty"`
49+
Street *string `json:"street,omitempty"`
50+
HouseNumber *string `json:"house_number,omitempty"`
51+
PostalCode *string `json:"postal_code,omitempty"`
52+
City *string `json:"city,omitempty"`
53+
Country *string `json:"country,omitempty"`
54+
State *string `json:"state,omitempty"`
55+
ContactEmail *string `json:"contact_email,omitempty"`
56+
ContactPhone *string `json:"contact_phone,omitempty"`
57+
WebsiteLink *string `json:"website_link,omitempty"`
58+
Lon *float64 `json:"lon,omitempty"`
59+
Lat *float64 `json:"lat,omitempty"`
60+
Organization *OrganizationResult `json:"organization,omitempty"`
61+
Spaces []SpaceResult `json:"spaces,omitempty"`
62+
}
63+
64+
venueId, ok := ParamInt(gc, "venueId")
65+
if !ok {
66+
apiRequest.Error(http.StatusBadRequest, "venue Id is required")
67+
return
68+
}
69+
70+
lang := gc.DefaultQuery("lang", "en")
71+
apiRequest.SetMeta("language", lang)
72+
73+
query := app.UranusInstance.SqlGetVenue
74+
75+
row := h.DbPool.QueryRow(ctx, query, venueId, lang)
76+
77+
// Temporary variables for SQL scan
78+
var venue VenueResult
79+
var org OrganizationResult
80+
var spacesJSON []byte
81+
82+
err := row.Scan(
83+
&venue.Id,
84+
&venue.Name,
85+
&venue.Type,
86+
&venue.TypeName,
87+
&venue.TypeDescription,
88+
&venue.OpenedAt,
89+
&venue.ClosedAt,
90+
&venue.Description,
91+
&venue.Street,
92+
&venue.HouseNumber,
93+
&venue.PostalCode,
94+
&venue.City,
95+
&venue.Country,
96+
&venue.State,
97+
&venue.ContactEmail,
98+
&venue.ContactPhone,
99+
&venue.WebsiteLink,
100+
&venue.Lon,
101+
&venue.Lat,
102+
&org.Id,
103+
&org.Name,
104+
&org.WebsiteLink,
105+
&org.City,
106+
&org.Country,
107+
&spacesJSON,
108+
)
109+
if err != nil {
110+
debugf("GetVenue error: %v", err)
111+
apiRequest.SetMeta("err_code", "1001")
112+
apiRequest.InternalServerError()
113+
return
114+
}
115+
116+
// Assign organization if any fields are non-nil
117+
if org.Name != nil || org.WebsiteLink != nil || org.City != nil || org.Country != nil {
118+
venue.Organization = &org
119+
}
120+
121+
// Decode spaces JSON into structs
122+
if len(spacesJSON) > 0 {
123+
if err := json.Unmarshal(spacesJSON, &venue.Spaces); err != nil {
124+
apiRequest.SetMeta("err_code", "1002")
125+
apiRequest.InternalServerError()
126+
return
127+
}
128+
}
129+
130+
apiRequest.Success(http.StatusOK, venue, "")
131+
}

app/uranus.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ type Uranus struct {
2828
MainDbPool *pgxpool.Pool
2929
Config Config
3030
SqlGetOrganization string
31+
SqlGetVenue string
3132
SqlGetEvent string
3233
SqlGetEventDates string
3334
SqlGetEventsProjected string
@@ -262,6 +263,7 @@ func (app *Uranus) PrepareSql() error {
262263
{"sql/choosable-venue-spaces.sql", &app.SqlChoosableVenueSpaces, nil},
263264

264265
{"sql/get-organization.sql", &app.SqlGetOrganization, nil},
266+
{"sql/get-venue.sql", &app.SqlGetVenue, nil},
265267

266268
// Admin
267269

sql/get-venue.sql

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
SELECT
2+
v.id,
3+
v.name,
4+
v.type,
5+
vti.name AS type_name,
6+
vti.description AS type_description,
7+
TO_CHAR(v.opened_at, 'YYYY-MM-DD') AS opened_at,
8+
TO_CHAR(v.closed_at, 'YYYY-MM-DD') AS closed_at,
9+
v.description,
10+
v.street,
11+
v.house_number,
12+
v.postal_code,
13+
v.city,
14+
v.country,
15+
v.state,
16+
v.contact_email,
17+
v.contact_phone,
18+
v.website_link,
19+
ST_X(v.geo_pos) AS lon,
20+
ST_Y(v.geo_pos) AS lat,
21+
v.organization_id,
22+
23+
o.name AS org_name,
24+
o.website_link AS org_website_link,
25+
o.city AS org_city,
26+
o.country AS org_country,
27+
28+
COALESCE(
29+
json_agg(
30+
json_build_object(
31+
'id', s.id,
32+
'name', s.name,
33+
'total_capacity', s.total_capacity,
34+
'seating_capacity', s.seating_capacity,
35+
'building_level', s.building_level,
36+
'website_link', s.website_link,
37+
'description', s.description,
38+
'area_sqm', s.area_sqm,
39+
'space_type', s.space_type,
40+
'space_type_name', sti.name,
41+
'space_type_description', sti.description
42+
)
43+
) FILTER (WHERE s.id IS NOT NULL),
44+
'[]'
45+
) AS spaces
46+
47+
FROM {{schema}}.venue v
48+
LEFT JOIN {{schema}}.organization o ON o.id = v.organization_id
49+
LEFT JOIN {{schema}}.space s ON s.venue_id = v.id
50+
51+
LEFT JOIN {{schema}}.venue_type vt ON vt.key = v.type
52+
LEFT JOIN {{schema}}.venue_type_i18n vti
53+
ON vti.key = vt.key
54+
AND vti.iso_639_1 = $2
55+
56+
LEFT JOIN {{schema}}.space_type st ON st.key = s.space_type
57+
LEFT JOIN {{schema}}.space_type_i18n sti
58+
ON sti.key = st.key
59+
AND sti.iso_639_1 = $2
60+
61+
WHERE v.id = $1
62+
GROUP BY
63+
v.id,
64+
o.id,
65+
vti.name,
66+
vti.description

uranus-api.go

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,10 @@ func main() {
107107

108108
publicRoute.GET("/geojson/venues", apiHandler.GetGeojsonVenues) // TODO: check!
109109

110-
publicRoute.GET("/organizations", apiHandler.GetOrganizations) // TODO: check!
110+
publicRoute.GET("/organization/:organizationId", apiHandler.GetOrganization) // TODO: check!
111+
publicRoute.GET("/organizations", apiHandler.GetOrganizations) // TODO: check!
112+
113+
publicRoute.GET("/venue/:venueId", apiHandler.GetVenue)
111114

112115
publicRoute.GET("/user/:userId/avatar/:size", apiHandler.GetUserAvatar) // TODO: check!
113116
publicRoute.GET("/user/:userId/avatar", apiHandler.GetUserAvatar) // TODO: check!
@@ -134,8 +137,6 @@ func main() {
134137

135138
publicRoute.GET("/accessibility/flags", apiHandler.GetAccessibilityFlags) // TODO: check!
136139

137-
publicRoute.GET("/organization/:organizationId", apiHandler.GetOrganization) // TODO: check!
138-
139140
// Inject app middleware into Pluto's image routes
140141
pluto.PlutoInstance.RegisterRoutes(publicRoute, app.JWTMiddleware) // TODO: check!
141142

0 commit comments

Comments
 (0)