This repository has been archived on 2021-10-31. You can view files and clone it, but cannot push or open issues or pull requests.
SA3/hw7/Claudio_Maggioni/routes/root/router.js

230 lines
5.7 KiB
JavaScript

/** @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 { error } = require('../utils');
router.get('/', (req, res) => {
Favorite.find({}, (err, favs) => {
if (err) {
return error(err, res);
}
res.render('index.dust', { favs });
});
});
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;
}
console.log(req.body.favorites);
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(e);
}
});
/** router for /root */
module.exports = router;