2023-04-05 13:40:00 +07:00
|
|
|
const config = require('./config.json')
|
|
|
|
|
|
|
|
const domain = config.domain;
|
2023-04-08 10:34:31 +07:00
|
|
|
const host = config.host;
|
2023-04-05 13:40:00 +07:00
|
|
|
const port = config.port;
|
|
|
|
const openWebBrowser = config.openWebBrowser; // Set to false if running as a server
|
|
|
|
|
2023-04-08 10:57:44 +07:00
|
|
|
let full_url = "";
|
|
|
|
const https = config.https;
|
|
|
|
if(https) {
|
|
|
|
full_url = "https://" + domain + ":" + port;
|
|
|
|
} else {
|
|
|
|
full_url = "http://" + domain + ":" + port;
|
|
|
|
}
|
|
|
|
|
|
|
|
console.log("Server running on: " + full_url);
|
|
|
|
|
2023-04-05 13:40:00 +07:00
|
|
|
// Doesn't matter what Google account holds these keys.
|
|
|
|
const clientId = config.clientId // Client ID from Google API page
|
|
|
|
const clientSecret = config.clientSecret // Client Secret from Google API page
|
|
|
|
|
|
|
|
// Part 1: Open web browser to login to Google account and receive access token
|
|
|
|
const open = require('open');
|
|
|
|
if (openWebBrowser) {
|
|
|
|
(async () => {
|
2023-04-08 10:57:44 +07:00
|
|
|
await open(full_url);
|
2023-04-05 13:40:00 +07:00
|
|
|
})();
|
|
|
|
}
|
|
|
|
|
2023-04-08 10:34:31 +07:00
|
|
|
const favicon = require('serve-favicon');
|
2023-04-05 13:40:00 +07:00
|
|
|
const express = require('express')
|
|
|
|
const bodyParser = require('body-parser');
|
|
|
|
const cookieParser = require('cookie-parser')
|
|
|
|
const upload = require("express-fileupload");
|
|
|
|
const request = require("request");
|
|
|
|
const app = express()
|
|
|
|
app.use(bodyParser.urlencoded({extended: true}));
|
|
|
|
app.use(cookieParser());
|
|
|
|
app.use(
|
|
|
|
upload({
|
|
|
|
preserveExtension: true,
|
|
|
|
safeFileNames: true,
|
|
|
|
limits: {fileSize: 75 * 1024 * 1024},
|
|
|
|
})
|
|
|
|
);
|
2023-04-08 10:34:31 +07:00
|
|
|
// CSS and JS Files
|
|
|
|
app.use(express.static(__dirname + '/public'));
|
|
|
|
|
|
|
|
app.set('view engine', 'ejs');
|
|
|
|
|
|
|
|
app.use(favicon(__dirname + '/public/assets/icons/favicon.ico'));
|
|
|
|
|
2023-04-05 13:40:00 +07:00
|
|
|
app.get('/', function (req, res) {
|
2023-04-08 10:34:31 +07:00
|
|
|
res.render('pages/index', {
|
2023-04-08 10:57:44 +07:00
|
|
|
full_url: full_url,
|
2023-04-08 10:34:31 +07:00
|
|
|
clientId: clientId
|
|
|
|
});
|
2023-04-05 13:40:00 +07:00
|
|
|
})
|
2023-04-08 10:34:31 +07:00
|
|
|
|
|
|
|
app.get('/upload', function(req, res){
|
|
|
|
res.render('pages/upload');
|
2023-04-05 13:40:00 +07:00
|
|
|
})
|
2023-04-08 10:34:31 +07:00
|
|
|
|
2023-04-05 13:40:00 +07:00
|
|
|
app.post('/upload', function (req, res) {
|
2023-04-08 10:34:31 +07:00
|
|
|
|
|
|
|
let latitude = req.body["lat"];
|
|
|
|
let longitude = req.body["long"];
|
|
|
|
|
2023-04-05 13:40:00 +07:00
|
|
|
let key = req.cookies["oauth"]
|
|
|
|
if (!key) {
|
|
|
|
return res.redirect('/')
|
|
|
|
} else {
|
|
|
|
if (!req.files) {
|
2023-04-08 10:34:31 +07:00
|
|
|
return res.status(400).render('pages/error', {
|
|
|
|
errorCode: 400,
|
|
|
|
errorStatus: "Missing File",
|
|
|
|
errorMessage: "Missing File",
|
|
|
|
response: "Error: Missing File"
|
|
|
|
})
|
|
|
|
|
2023-04-05 13:40:00 +07:00
|
|
|
} else {
|
|
|
|
// Part 1: Get uploadUrl
|
|
|
|
const options = {
|
|
|
|
'method': 'POST',
|
2023-04-06 08:02:56 +07:00
|
|
|
'url': `https://streetviewpublish.googleapis.com/v1/photo:startUpload`,
|
2023-04-05 13:40:00 +07:00
|
|
|
'headers': {
|
|
|
|
'Authorization': `Bearer ${key}`
|
|
|
|
}
|
|
|
|
// For authorization token, must use oauth 2.0
|
|
|
|
};
|
|
|
|
request(options, function (error, response) {
|
|
|
|
if (error) {
|
2023-04-08 10:34:31 +07:00
|
|
|
console.log(error)
|
|
|
|
res.status(500).render('pages/error', {
|
|
|
|
errorCode: 500,
|
|
|
|
errorStatus: "ERROR",
|
|
|
|
errorMessage: "Error: Error with getting upload url",
|
|
|
|
response: JSON.stringify(JSON.parse(response.body), null, 4)
|
|
|
|
})
|
2023-04-05 13:40:00 +07:00
|
|
|
} else {
|
|
|
|
let uploadUrl = JSON.parse(response.body)["uploadUrl"]
|
|
|
|
// PART 2: Upload the image!
|
|
|
|
const options = {
|
|
|
|
'method': 'POST',
|
|
|
|
'url': uploadUrl,
|
|
|
|
'headers': {
|
|
|
|
'Authorization': `Bearer ${key}`,
|
|
|
|
},
|
|
|
|
body: req.files.file.data
|
|
|
|
};
|
|
|
|
request(options, function (error) {
|
|
|
|
if (error) {
|
2023-04-08 10:34:31 +07:00
|
|
|
console.log(error)
|
|
|
|
|
|
|
|
res.status(500).render('pages/error', {
|
|
|
|
errorCode: 500,
|
|
|
|
errorStatus: "UPLOAD ERROR",
|
|
|
|
errorMessage: "Error: Error with uploading file to Google's API",
|
|
|
|
response: error
|
|
|
|
})
|
|
|
|
|
2023-04-05 13:40:00 +07:00
|
|
|
} else {
|
|
|
|
//PART 3: Set metadata!
|
2023-04-06 06:32:37 +07:00
|
|
|
let body;
|
|
|
|
if (req.body["lat"] && req.body["long"]) {
|
|
|
|
body = JSON.stringify({
|
2023-04-05 13:40:00 +07:00
|
|
|
"uploadReference": {
|
|
|
|
"uploadUrl": uploadUrl
|
|
|
|
},
|
|
|
|
"pose": {
|
|
|
|
"latLngPair": {
|
2023-04-08 10:34:31 +07:00
|
|
|
"latitude": latitude,
|
|
|
|
"longitude": longitude
|
2023-04-05 13:40:00 +07:00
|
|
|
},
|
|
|
|
"heading": 0
|
|
|
|
}
|
|
|
|
})
|
2023-04-06 06:32:37 +07:00
|
|
|
} else {
|
|
|
|
body = JSON.stringify({
|
|
|
|
"uploadReference": {
|
|
|
|
"uploadUrl": uploadUrl
|
|
|
|
},
|
|
|
|
})
|
|
|
|
}
|
2023-04-05 13:40:00 +07:00
|
|
|
|
2023-04-06 06:32:37 +07:00
|
|
|
const options = {
|
|
|
|
'method': 'POST',
|
2023-04-06 08:02:56 +07:00
|
|
|
'url': `https://streetviewpublish.googleapis.com/v1/photo`,
|
2023-04-06 06:32:37 +07:00
|
|
|
'headers': {
|
|
|
|
'Authorization': `Bearer ${key}`,
|
|
|
|
'Content-Type': 'application/json'
|
|
|
|
},
|
|
|
|
body: body
|
2023-04-05 13:40:00 +07:00
|
|
|
};
|
|
|
|
request(options, function (error, response) {
|
|
|
|
if (error) {
|
2023-04-08 10:34:31 +07:00
|
|
|
console.log(error)
|
|
|
|
|
|
|
|
res.status(500).render('pages/error', {
|
|
|
|
errorCode: 500,
|
|
|
|
errorStatus: "ERROR",
|
|
|
|
errorMessage: "Error with setting metadata of file",
|
|
|
|
response: "Error: Error with setting metadata of file"
|
|
|
|
})
|
|
|
|
|
2023-04-05 13:40:00 +07:00
|
|
|
} else {
|
2023-04-06 06:32:37 +07:00
|
|
|
if (JSON.parse(response.body)["error"]) {
|
2023-04-08 10:34:31 +07:00
|
|
|
res.status(500).render('pages/error', {
|
|
|
|
errorCode: JSON.parse(response.body)["error"]["code"],
|
|
|
|
errorStatus: JSON.parse(response.body)["error"]["status"],
|
|
|
|
errorMessage: JSON.parse(response.body)["error"]["message"],
|
|
|
|
response: JSON.stringify(JSON.parse(response.body), null, 4),
|
|
|
|
});
|
|
|
|
} else {
|
|
|
|
let shareLink = JSON.parse(response.body)["shareLink"]
|
|
|
|
res.status(200).render('pages/success', {
|
|
|
|
status: JSON.parse(response.body)["mapsPublishStatus"],
|
|
|
|
shareLink: shareLink,
|
|
|
|
response: JSON.stringify(JSON.parse(response.body), null, 4)
|
|
|
|
});
|
2023-04-06 06:32:37 +07:00
|
|
|
}
|
2023-04-05 13:40:00 +07:00
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
})
|
|
|
|
// We contact Google to get a temporary token that only has permission to upload PhotoSpheres.
|
|
|
|
app.get('/auth', function (req, res) {
|
|
|
|
const request = require('request');
|
|
|
|
const options = {
|
|
|
|
'method': 'POST',
|
2023-04-08 10:57:44 +07:00
|
|
|
'url': `https://www.googleapis.com/oauth2/v4/token?client_id=${clientId}&client_secret=${clientSecret}&grant_type=authorization_code&code=${req.query["code"]}&redirect_uri=${full_url}/auth/&scope=https://www.googleapis.com/auth/streetviewpublish`,
|
2023-04-05 13:40:00 +07:00
|
|
|
'headers': {}
|
|
|
|
};
|
|
|
|
request(options, function (error, response) {
|
|
|
|
if (error) console.log(error) && res.send("Error: Check console");
|
2023-04-06 06:32:37 +07:00
|
|
|
res.cookie('oauth', JSON.parse(response.body)["access_token"], {
|
|
|
|
maxAge: JSON.parse(response.body)["expires_in"] * 1000,
|
|
|
|
httpOnly: true
|
|
|
|
});
|
2023-04-08 10:34:31 +07:00
|
|
|
res.render('pages/upload')
|
2023-04-05 13:40:00 +07:00
|
|
|
});
|
|
|
|
|
|
|
|
})
|
|
|
|
|
|
|
|
app.listen(port)
|