-
Notifications
You must be signed in to change notification settings - Fork 0
/
index.js
106 lines (88 loc) · 4.05 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
const express = require('express')
const weather = require('./src/weatherAPI.js')
const {geolocateFromIP} = require('./src/geoipAPI.js')
const anonymizeip = require('./src/anonymizeip.js')
var path = require('path');
const PORT = process.env.PORT || 3000
const HOST = '0.0.0.0'
// !* Edit here for demos
const RELEASE_NO = 'DEMO-2'
const api = express()
api.set('views', path.join(__dirname, 'views'));
api.set('view engine', 'pug');
api.use(express.static(path.join(__dirname, 'public')));
// Define the main route for the sample app. When the homepage of the sample app
// is requested, the server will first determine the client's geolocation based
// on the client's IP address.
api.get('/', (req, res) => {
const clientIP = req.ip
const renderValues = {
release_no: RELEASE_NO,
ipAddr: anonymizeip(clientIP),
}
// For the initial page load on the main route, the server will attempt to
// geolocate the user based on their IP address. If the geolocation is
// successful, the server will then call the weather API with the coordinates
// and timezone obtained from the geolocation API. If the geolocation fails,
// the server will default to Toronto, Ontario, Canada, and call the weather
// API with the coordinates and timezone for Toronto.
const weatherResp = geolocateFromIP(clientIP).then((coords) => {
// If the geolocation is successful, format the name of the returned location,
// then call the weather API with the coordinates and timezone.
renderValues.locationName = coords.locationName
return weather(coords.lat, coords.lon, coords.timezone)
}).catch(() => {
// If the geolocation fails, default to Toronto, Ontario, Canada, then call
// the weather API with the coordinates and timezone.
renderValues.locationName = "Toronto, Ontario, Canada"
return weather("43.7", "-79.42", "America/Toronto")
})
weatherResp.then((weatherData) => {
// Once the weather API call is successful, render the index page with the
// template values specified in `renderValues`.
renderValues.forecast = weatherData
return res.render('index', renderValues, function (err, html) {
if (err) {
console.error("Error rendering index page:", err)
return res.status(500).send('An error occurred while rendering the page.')
} else {
return res.send(html)
}
})
}).catch((e) => {
// If the weather API call fails, render the index page with the template
// and the limited values that are available.
console.error("Error in main route:", e)
res.render('index', renderValues, function (err, html) {
if (err) {
console.error("Error rendering index page:", err)
return res.status(500).send('An error occurred while rendering the page.')
} else {
return res.send(html)
}
})
})
})
api.get('/geolocate', (req, res) => {
// If the geolocation permission is denied on the client side, the client
// will send a request to `/geolocate` to get the estimated coordinates
// of the client's IP address. This will then return the coordinates to the
// client, which will use them to call the weather API as it normally would.
geolocateFromIP(req.ip)
.then(coords => res.json(coords))
.catch(e => res.json({status: 'error', code: 500, message: e.message}))
})
api.get('/weather', (req, res) => {
const queryParams = req.query
if (!queryParams.lat || !queryParams.lon || !queryParams.timezone) {
res.status(400).send('Missing query parameters. All of the following are required: lat, lon, timezone')
return
}
weather(queryParams.lat, queryParams.lon, queryParams.timezone).then((weatherData) => {
res.json(weatherData)
}).catch((e) => {
res.json({status: 'error', code: 500, message: e.message})
})
})
api.listen(PORT, HOST)
console.log(`Running on http://${HOST}:${PORT}`)