HW7: preparing for 1st submission
This commit is contained in:
parent
8ea7a1f825
commit
95729f6e20
4 changed files with 283 additions and 256 deletions
|
@ -48,6 +48,7 @@ app.use('/', routers.root);
|
||||||
app.use('/favorites', routers.favourites_db_asaw);
|
app.use('/favorites', routers.favourites_db_asaw);
|
||||||
app.use('/bookmarked', routers.bookmarked);
|
app.use('/bookmarked', routers.bookmarked);
|
||||||
app.use('/test/fetch', routers.fetch_tests);
|
app.use('/test/fetch', routers.fetch_tests);
|
||||||
|
app.use('/imgur', routers.imgur);
|
||||||
|
|
||||||
app.set('port', process.env.PORT || 3000);
|
app.set('port', process.env.PORT || 3000);
|
||||||
const server = app.listen(app.get('port'), function() {
|
const server = app.listen(app.get('port'), function() {
|
||||||
|
@ -89,6 +90,8 @@ eventBus.on('favorite.deleted', (event) => {
|
||||||
io.emit('favorite.deleted', event);
|
io.emit('favorite.deleted', event);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Imgur auth url open code
|
||||||
|
|
||||||
const { exec } = require('child_process');
|
const { exec } = require('child_process');
|
||||||
const client = '3710c666dbec94e';
|
const client = '3710c666dbec94e';
|
||||||
const imgURL = `https://api.imgur.com/oauth2/authorize?client_id=${client}` +
|
const imgURL = `https://api.imgur.com/oauth2/authorize?client_id=${client}` +
|
||||||
|
|
6
hw7/Claudio_Maggioni/readme.md
Normal file
6
hw7/Claudio_Maggioni/readme.md
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
# Bonuses implemented
|
||||||
|
|
||||||
|
- Task 3 bookmarked code
|
||||||
|
- Task 6
|
||||||
|
- Task 7
|
||||||
|
- Access token fetching from authorization url
|
274
hw7/Claudio_Maggioni/routes/imgur/router.js
Normal file
274
hw7/Claudio_Maggioni/routes/imgur/router.js
Normal file
|
@ -0,0 +1,274 @@
|
||||||
|
/** @module root/router */
|
||||||
|
'use strict';
|
||||||
|
// vim: set ts=2 sw=2 et tw=80:
|
||||||
|
|
||||||
|
const express = require('express');
|
||||||
|
const router = express.Router();
|
||||||
|
|
||||||
|
const mongoose = require('mongoose');
|
||||||
|
const Favorite = mongoose.model('Favorite');
|
||||||
|
const fetch = require('node-fetch');
|
||||||
|
const querystring = require('querystring');
|
||||||
|
const promiseAny = require('promise-any');
|
||||||
|
const eventBus = require('../../pubsub');
|
||||||
|
const fetch64 = require('fetch-base64');
|
||||||
|
|
||||||
|
router.get('/', (req, res) => {
|
||||||
|
if (req.query.access_token) {
|
||||||
|
req.app.locals.imgur = req.query;
|
||||||
|
res.redirect('/');
|
||||||
|
} else {
|
||||||
|
res.status(200, {'Content-Type': 'text/html'});
|
||||||
|
res.end(`<!DOCTYPE html><html><head><meta charset="utf-8"></head><body>
|
||||||
|
<script>
|
||||||
|
console.log(window.location.href);
|
||||||
|
if (window.location.href.indexOf("#access") != -1) {
|
||||||
|
window.location.href = window.location.href.replace("#access",
|
||||||
|
"?access");
|
||||||
|
}
|
||||||
|
</script></body></html>`);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
async function fetchImgur(req, res, method, url, body) {
|
||||||
|
const endpoint = 'https://api.imgur.com/3';
|
||||||
|
|
||||||
|
const response = await fetch(endpoint + url, {
|
||||||
|
method: method,
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/x-www-form-urlencoded',
|
||||||
|
'Authorization' : 'Bearer ' + req.app.locals.imgur.access_token
|
||||||
|
},
|
||||||
|
body: body ? querystring.stringify(body) : undefined
|
||||||
|
});
|
||||||
|
|
||||||
|
const json = await response.json();
|
||||||
|
|
||||||
|
if (json.status == 409 && url.match(/follow\/tag/)) {
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Math.floor(json.status / 100) != 2) {
|
||||||
|
res.status(json.status).json(json);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return json;
|
||||||
|
}
|
||||||
|
|
||||||
|
router.post('/ordeal', async (req, res) => {
|
||||||
|
try {
|
||||||
|
if ((!req.body.replace && (!req.body.name || !req.body.album)) ||
|
||||||
|
(req.body.replace && (!req.body.name || !req.body.oldName))) {
|
||||||
|
res.status(400).json({ error: "Malformed ordeal request" });
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const ordealResponse = { ordealSuccess: true };
|
||||||
|
|
||||||
|
const uploadData = {
|
||||||
|
image: req.body.dataURL.substring('data:image/png;base64,'.length),
|
||||||
|
type: 'base64',
|
||||||
|
title: req.body.name,
|
||||||
|
name: req.body.name + '.png',
|
||||||
|
};
|
||||||
|
|
||||||
|
const uploadJson = await fetchImgur(req, res, 'POST', '/upload', uploadData);
|
||||||
|
if (!uploadJson) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const imageId = uploadJson.data.id;
|
||||||
|
|
||||||
|
const albumData = {
|
||||||
|
'ids[]': imageId,
|
||||||
|
};
|
||||||
|
|
||||||
|
if (!req.body.replace) {
|
||||||
|
if (req.body.album) {
|
||||||
|
albumData.title = req.body.album;
|
||||||
|
}
|
||||||
|
|
||||||
|
const albumJson = await fetchImgur(req, res, 'POST', '/album', albumData);
|
||||||
|
if (!albumJson) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (req.body.favorites) {
|
||||||
|
if (!await fetchImgur(req, res, 'POST', '/album/' + albumJson.data.id +
|
||||||
|
'/favorite', {})) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
req.body.album = undefined;
|
||||||
|
|
||||||
|
const submissions = await fetchImgur(req, res, 'GET',
|
||||||
|
'/account/me/submissions');
|
||||||
|
|
||||||
|
if (!submissions) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const submission = submissions.data
|
||||||
|
.filter(e => !e.images && e.in_gallery &&
|
||||||
|
e.title == req.body.oldName)[0];
|
||||||
|
|
||||||
|
if (!submission) {
|
||||||
|
res.status(404).json({ error: "No image in submissions found" });
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log('submission', submission.id, submission.title);
|
||||||
|
|
||||||
|
const result = {};
|
||||||
|
result.image = submission;
|
||||||
|
ordealResponse.views = submission.views;
|
||||||
|
ordealResponse.votes = {};
|
||||||
|
ordealResponse.votes.ups = submission.ups;
|
||||||
|
ordealResponse.votes.downs = submission.downs;
|
||||||
|
|
||||||
|
const albumIds = await fetchImgur(req, res, 'GET',
|
||||||
|
'/account/me/albums/ids');
|
||||||
|
|
||||||
|
if (!albumIds) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log('albumIds', albumIds.data.join(','));
|
||||||
|
|
||||||
|
let reject = false;
|
||||||
|
const promises = [];
|
||||||
|
for (const albumId of albumIds.data) {
|
||||||
|
promises.push(new Promise(async (res, rej) => {
|
||||||
|
if (reject) {
|
||||||
|
return reject;
|
||||||
|
}
|
||||||
|
|
||||||
|
const images = await fetchImgur(req, res, 'GET', '/album/' +
|
||||||
|
albumId + '/images');
|
||||||
|
|
||||||
|
if (!images || reject) {
|
||||||
|
rej();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log('album', albumId, 'images', images.data.map(e => e.id));
|
||||||
|
|
||||||
|
const image = images.data.filter(e => e.id == result.image.id)[0];
|
||||||
|
|
||||||
|
|
||||||
|
if (!image || reject) {
|
||||||
|
rej();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
reject = true;
|
||||||
|
console.log('the album', albumId, 'image', image.id);
|
||||||
|
res(albumId);
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
result.albumId = await promiseAny(promises);
|
||||||
|
} catch(_) {
|
||||||
|
res.status(400).json({ error: "Image not found in any album" });
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!await fetchImgur(req, res, 'DELETE', '/image/' + result.image.id)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!await fetchImgur(req, res, 'PUT', '/album/' +
|
||||||
|
result.albumId + '/add', { 'ids[]': uploadJson.data.id })) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!await fetchImgur(req, res, 'POST', '/gallery/image/' +
|
||||||
|
uploadJson.data.id, { title: req.body.name, tags: req.body.tags })) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (req.body.tags) {
|
||||||
|
const tagsData = {
|
||||||
|
'tags': req.body.tags
|
||||||
|
};
|
||||||
|
|
||||||
|
if (!await fetchImgur(req, res, 'POST', '/gallery/tags/' +
|
||||||
|
uploadJson.data.id, tagsData)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const tag of req.body.tags.split(',')) {
|
||||||
|
if (!await fetchImgur(req, res, 'POST', '/account/me/follow/tag/' + tag,
|
||||||
|
{})) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
res.json(ordealResponse);
|
||||||
|
} catch(e) {
|
||||||
|
console.error(e);
|
||||||
|
res.status(500).json({ error: e.toString() });
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
router.post('/search', async (req, res) => {
|
||||||
|
try {
|
||||||
|
if (!req.body.name) {
|
||||||
|
res.status(400).json({ error: 'Bad parameters for /imgur/search' });
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const results = await fetchImgur(req, res, 'GET',
|
||||||
|
'/gallery/search/time/top/1?q=' +
|
||||||
|
encodeURIComponent(req.body.name) + '&q_type=png');
|
||||||
|
|
||||||
|
if (!results) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (results.data.length == 0) {
|
||||||
|
res.status(404).json({ error: 'No image found' });
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let image = results.data[0];
|
||||||
|
if (image.is_album) {
|
||||||
|
image = image.images[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!await fetchImgur(req, res, 'POST', '/gallery/' + results.data[0].id +
|
||||||
|
'/vote/up', {})) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!await fetchImgur(req, res, 'POST', '/image/' + image.id + '/favorite',
|
||||||
|
{})) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const fetch64res = await fetch64.remote(image.link);
|
||||||
|
|
||||||
|
const fav = {
|
||||||
|
_id: mongoose.Types.ObjectId(),
|
||||||
|
name: req.body.name,
|
||||||
|
dataURL: fetch64res[1],
|
||||||
|
bookmarked: false,
|
||||||
|
};
|
||||||
|
|
||||||
|
await new Favorite(fav).save();
|
||||||
|
eventBus.emit('favorite.created', fav);
|
||||||
|
|
||||||
|
res.json({ success: true });
|
||||||
|
} catch(e) {
|
||||||
|
console.error(e);
|
||||||
|
res.status(500).json({ error: e.toString() });
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
/** router for /root */
|
||||||
|
module.exports = router;
|
|
@ -24,261 +24,5 @@ router.get('/', (req, res) => {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
router.get('/imgur', (req, res) => {
|
|
||||||
if (req.query.access_token) {
|
|
||||||
req.app.locals.imgur = req.query;
|
|
||||||
res.redirect('/');
|
|
||||||
} else {
|
|
||||||
res.status(200, {'Content-Type': 'text/html'});
|
|
||||||
res.end(`<!DOCTYPE html><html><head><meta charset="utf-8"></head><body>
|
|
||||||
<script>
|
|
||||||
console.log(window.location.href);
|
|
||||||
if (window.location.href.indexOf("#access") != -1) {
|
|
||||||
window.location.href = window.location.href.replace("#access",
|
|
||||||
"?access");
|
|
||||||
}
|
|
||||||
</script></body></html>`);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
async function fetchImgur(req, res, method, url, body) {
|
|
||||||
const endpoint = 'https://api.imgur.com/3';
|
|
||||||
|
|
||||||
const response = await fetch(endpoint + url, {
|
|
||||||
method: method,
|
|
||||||
headers: {
|
|
||||||
'Content-Type': 'application/x-www-form-urlencoded',
|
|
||||||
'Authorization' : 'Bearer ' + req.app.locals.imgur.access_token
|
|
||||||
},
|
|
||||||
body: body ? querystring.stringify(body) : undefined
|
|
||||||
});
|
|
||||||
|
|
||||||
const json = await response.json();
|
|
||||||
|
|
||||||
if (json.status == 409 && url.match(/follow\/tag/)) {
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Math.floor(json.status / 100) != 2) {
|
|
||||||
res.status(json.status).json(json);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return json;
|
|
||||||
}
|
|
||||||
|
|
||||||
router.post('/imgur/ordeal', async (req, res) => {
|
|
||||||
try {
|
|
||||||
if ((!req.body.replace && (!req.body.name || !req.body.album)) ||
|
|
||||||
(req.body.replace && (!req.body.name || !req.body.oldName))) {
|
|
||||||
res.status(400).json({ error: "Malformed ordeal request" });
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const ordealResponse = { ordealSuccess: true };
|
|
||||||
|
|
||||||
const uploadData = {
|
|
||||||
image: req.body.dataURL.substring('data:image/png;base64,'.length),
|
|
||||||
type: 'base64',
|
|
||||||
title: req.body.name,
|
|
||||||
name: req.body.name + '.png',
|
|
||||||
};
|
|
||||||
|
|
||||||
const uploadJson = await fetchImgur(req, res, 'POST', '/upload', uploadData);
|
|
||||||
if (!uploadJson) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const imageId = uploadJson.data.id;
|
|
||||||
|
|
||||||
const albumData = {
|
|
||||||
'ids[]': imageId,
|
|
||||||
};
|
|
||||||
|
|
||||||
if (!req.body.replace) {
|
|
||||||
if (req.body.album) {
|
|
||||||
albumData.title = req.body.album;
|
|
||||||
}
|
|
||||||
|
|
||||||
const albumJson = await fetchImgur(req, res, 'POST', '/album', albumData);
|
|
||||||
if (!albumJson) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (req.body.favorites) {
|
|
||||||
if (!await fetchImgur(req, res, 'POST', '/album/' + albumJson.data.id +
|
|
||||||
'/favorite', {})) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
req.body.album = undefined;
|
|
||||||
|
|
||||||
const submissions = await fetchImgur(req, res, 'GET',
|
|
||||||
'/account/me/submissions');
|
|
||||||
|
|
||||||
if (!submissions) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const submission = submissions.data
|
|
||||||
.filter(e => !e.images && e.in_gallery &&
|
|
||||||
e.title == req.body.oldName)[0];
|
|
||||||
|
|
||||||
if (!submission) {
|
|
||||||
res.status(404).json({ error: "No image in submissions found" });
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
console.log('submission', submission.id, submission.title);
|
|
||||||
|
|
||||||
const result = {};
|
|
||||||
result.image = submission;
|
|
||||||
ordealResponse.views = submission.views;
|
|
||||||
ordealResponse.votes = {};
|
|
||||||
ordealResponse.votes.ups = submission.ups;
|
|
||||||
ordealResponse.votes.downs = submission.downs;
|
|
||||||
|
|
||||||
const albumIds = await fetchImgur(req, res, 'GET',
|
|
||||||
'/account/me/albums/ids');
|
|
||||||
|
|
||||||
if (!albumIds) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
console.log('albumIds', albumIds.data.join(','));
|
|
||||||
|
|
||||||
let reject = false;
|
|
||||||
const promises = [];
|
|
||||||
for (const albumId of albumIds.data) {
|
|
||||||
promises.push(new Promise(async (res, rej) => {
|
|
||||||
if (reject) {
|
|
||||||
return reject;
|
|
||||||
}
|
|
||||||
|
|
||||||
const images = await fetchImgur(req, res, 'GET', '/album/' +
|
|
||||||
albumId + '/images');
|
|
||||||
|
|
||||||
if (!images || reject) {
|
|
||||||
rej();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
console.log('album', albumId, 'images', images.data.map(e => e.id));
|
|
||||||
|
|
||||||
const image = images.data.filter(e => e.id == result.image.id)[0];
|
|
||||||
|
|
||||||
|
|
||||||
if (!image || reject) {
|
|
||||||
rej();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
reject = true;
|
|
||||||
console.log('the album', albumId, 'image', image.id);
|
|
||||||
res(albumId);
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
result.albumId = await promiseAny(promises);
|
|
||||||
} catch(_) {
|
|
||||||
res.status(400).json({ error: "Image not found in any album" });
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!await fetchImgur(req, res, 'DELETE', '/image/' + result.image.id)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!await fetchImgur(req, res, 'PUT', '/album/' +
|
|
||||||
result.albumId + '/add', { 'ids[]': uploadJson.data.id })) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!await fetchImgur(req, res, 'POST', '/gallery/image/' +
|
|
||||||
uploadJson.data.id, { title: req.body.name, tags: req.body.tags })) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (req.body.tags) {
|
|
||||||
const tagsData = {
|
|
||||||
'tags': req.body.tags
|
|
||||||
};
|
|
||||||
|
|
||||||
if (!await fetchImgur(req, res, 'POST', '/gallery/tags/' +
|
|
||||||
uploadJson.data.id, tagsData)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (const tag of req.body.tags.split(',')) {
|
|
||||||
if (!await fetchImgur(req, res, 'POST', '/account/me/follow/tag/' + tag,
|
|
||||||
{})) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
res.json(ordealResponse);
|
|
||||||
} catch(e) {
|
|
||||||
console.error(e);
|
|
||||||
res.status(500).json({ error: e.toString() });
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
router.post('/imgur/search', async (req, res) => {
|
|
||||||
try {
|
|
||||||
if (!req.body.name) {
|
|
||||||
res.status(400).json({ error: 'Bad parameters for /imgur/search' });
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const results = await fetchImgur(req, res, 'GET', '/gallery/search/time/top/1?q=' +
|
|
||||||
encodeURIComponent(req.body.name) + '&q_type=png');
|
|
||||||
|
|
||||||
if (!results) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (results.data.length == 0) {
|
|
||||||
res.status(404).json({ error: 'No image found' });
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
let image = results.data[0];
|
|
||||||
if (image.is_album) {
|
|
||||||
image = image.images[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!await fetchImgur(req, res, 'POST', '/gallery/' + results.data[0].id +
|
|
||||||
'/vote/up', {})) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!await fetchImgur(req, res, 'POST', '/image/' + image.id + '/favorite',
|
|
||||||
{})) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const fetch64res = await fetch64.remote(image.link);
|
|
||||||
|
|
||||||
const fav = {
|
|
||||||
_id: mongoose.Types.ObjectId(),
|
|
||||||
name: req.body.name,
|
|
||||||
dataURL: fetch64res[1],
|
|
||||||
bookmarked: false,
|
|
||||||
};
|
|
||||||
|
|
||||||
await new Favorite(fav).save();
|
|
||||||
eventBus.emit('favorite.created', fav);
|
|
||||||
|
|
||||||
res.json({ success: true });
|
|
||||||
} catch(e) {
|
|
||||||
console.error(e);
|
|
||||||
res.status(500).json({ error: e.toString() });
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
/** router for /root */
|
/** router for /root */
|
||||||
module.exports = router;
|
module.exports = router;
|
||||||
|
|
Reference in a new issue