diff --git a/hw7/Claudio_Maggioni/inedito.txt b/hw7/Claudio_Maggioni/inedito.txt new file mode 100644 index 0000000..4e9b5b1 --- /dev/null +++ b/hw7/Claudio_Maggioni/inedito.txt @@ -0,0 +1,30 @@ +Nei giardini che nessuno sa - Renato NULL + +Senti quella POST ruvida +Un gran freddo dentro l'anima +Fa fatica anche una GET a scendere giù +Troppe await dietro l'angolo +{success: true} che non ti appartengono +Questo OAuth inconciliabile gioca contro di te + +Ecco come si finisce poi +In catch e console.error noi +Spettatori malinconici di j-j-javascript impossibili +Tanti bonus rimandati e gia' +Response vuote da un'eternità +Quella throw che non sai cos'è +Solo lei non ti abbandonerà... mai, oh mai + +Ti darei i sorgenti per far fetch come non sai +L'energia, l'allegria per yarn start e yarn run dustc +Dirti due, sempre due-cento e farti eseguire +Dove vuoi, dove sai senza più quel JSON sul cuore +Nasconderti gli errori, quel server node sul tereh-rminale +Curarti le ferite e poi qualche log in più per testare +E poi vederti terminar e poi vederti ritornar ora +Dimentica, c'è chi dimentica distrattamente un for una domenica + +E poi silenzi +E poi silenzi +Silenzi + diff --git a/hw7/Claudio_Maggioni/package.json b/hw7/Claudio_Maggioni/package.json index 7e373b3..4eb3b3d 100644 --- a/hw7/Claudio_Maggioni/package.json +++ b/hw7/Claudio_Maggioni/package.json @@ -29,6 +29,7 @@ "mongoose": "^5.7.7", "morgan": "^1.9.0", "node-fetch": "^2.6.0", + "promise-any": "^0.2.0", "request": "^2.88.0", "socket.io": "^2.3.0", "supertest": "^3.0.0" diff --git a/hw7/Claudio_Maggioni/public/scripts/app.js b/hw7/Claudio_Maggioni/public/scripts/app.js index 71bcb77..bd16af5 100644 --- a/hw7/Claudio_Maggioni/public/scripts/app.js +++ b/hw7/Claudio_Maggioni/public/scripts/app.js @@ -2,9 +2,9 @@ class App { static get BRUSHES() { return { - "PenBrush": new PenBrush(), - "DiscBrush": new DiscBrush(), - "StarBrush": new StarBrush(), + 'PenBrush': new PenBrush(), + 'DiscBrush': new DiscBrush(), + 'StarBrush': new StarBrush(), }; } @@ -14,13 +14,25 @@ class App { socketSessionId = null; registerFavoriteEvents(_id, dom) { - const imgurForm = dom.querySelector('form.favorites'); + const replaceToggle = dom.querySelector('input[name=replace]'); + const albumInput = imgurForm.querySelector('input[name=album]'); + const replacePanel = imgurForm.querySelector('.replace'); dom.querySelector('button.imgur').onclick = () => { imgurForm.classList.toggle('hidden'); }; + replaceToggle.onclick = () => { + if (replaceToggle.checked) { + replacePanel.classList.remove('hidden'); + albumInput.setAttribute('disabled', 'disabled'); + } else { + replacePanel.classList.add('hidden'); + albumInput.removeAttribute('disabled'); + } + }; + imgurForm.onsubmit = e => { imgurForm.classList.remove('ok'); imgurForm.classList.remove('err'); @@ -30,11 +42,14 @@ class App { const obj = { dataURL: data.get('dataURL'), name: dom.querySelector('form.data input[name=name]').value, + replace: data.get('replace'), + oldName: data.get('old_name'), album: data.get('album'), tags: data.get('tags'), favorites: data.get('favorites') }; + doJSONRequest('POST', '/imgur/ordeal', {}, obj) .then(e => { if (e.ordealSuccess === true) { @@ -52,7 +67,7 @@ class App { const delay = (f, ...args) => { const execute = (f, ...args) => { - console.log("don't delay, solve Carzaniga today", ...args); + console.log('don\'t delay, solve Carzaniga today', ...args); this.render_timestamp = new Date().getTime(); this.render_timeout = null; this.render_last = null; @@ -60,7 +75,7 @@ class App { }; if (new Date().getTime() - this.render_timestamp < 100000) { - console.log("delaying", ...args); + console.log('delaying', ...args); this.render_last = () => execute(f, ...args); if (this.render_timeout === null) { this.render_timeout = setTimeout(() => this.render_last(), 100); @@ -190,20 +205,20 @@ class App { const socket = io(); socket.on('connect', () => { - console.log("Socket connected"); + console.log('Socket connected'); }); socket.on('sessionId', (msg) => { - console.log("Socket session id is", msg.id); + console.log('Socket session id is', msg.id); this.socketSessionId = msg.id; }); socket.on('disconnect', (reason) => { - console.log("Socket disconnected"); + console.log('Socket disconnected'); }); socket.on('reconnect', (attemptNumber) => { - console.log("Socket reconnected"); + console.log('Socket reconnected'); }); socket.on('favorite.created', (msg) => { @@ -287,7 +302,7 @@ class App { bookmarked: false }; - doJSONRequest("POST", "/favorites?socketid=" + this.socketSessionId, + doJSONRequest('POST', '/favorites?socketid=' + this.socketSessionId, {}, data) .then(data => this.renderFavorite(data, 'top')) .catch(console.error); @@ -332,7 +347,7 @@ class App { this.ctx.lineWidth = 1; this.strokeStyle = this.constructor.defaultStrokeStyle; - this.brush = "PenBrush"; + this.brush = 'PenBrush'; const brushToolbar = document.querySelector('#brush-toolbar'); if (brushToolbar) { diff --git a/hw7/Claudio_Maggioni/public/style.css b/hw7/Claudio_Maggioni/public/style.css index 452797c..be93057 100644 --- a/hw7/Claudio_Maggioni/public/style.css +++ b/hw7/Claudio_Maggioni/public/style.css @@ -118,6 +118,7 @@ body { margin: 5px; float: left; width: 200px; + font-size: 0.7em; } #favourites img { @@ -131,3 +132,15 @@ body { padding: 15px; text-align: center; } + +.hidden { + display: none; +} + +.ok { + background-color: lightgreen; +} + +.err { + background-color: pink; +} diff --git a/hw7/Claudio_Maggioni/routes/root/router.js b/hw7/Claudio_Maggioni/routes/root/router.js index e76b412..27a3a17 100644 --- a/hw7/Claudio_Maggioni/routes/root/router.js +++ b/hw7/Claudio_Maggioni/routes/root/router.js @@ -9,6 +9,7 @@ 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'); @@ -41,29 +42,29 @@ router.get('/imgur', (req, res) => { async function fetchImgur(req, res, method, url, body) { const endpoint = 'https://api.imgur.com/3'; - const uploadRes = await fetch(endpoint + url, { + 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: querystring.stringify(body) + body: body ? querystring.stringify(body) : undefined }); - const uploadJson = await uploadRes.json(); + const json = await response.json(); - if (Math.floor(uploadJson.status / 100) != 2) { - res.status(uploadJson.status).json(uploadJson); + if (Math.floor(json.status / 100) != 2) { + res.status(json.status).json(json); return false; } - console.log(url, uploadJson); - - return uploadJson; + return json; } router.post('/imgur/ordeal', async (req, res) => { try { + const ordealResponse = { ordealSuccess: true }; + const uploadData = { image: req.body.dataURL.substring('data:image/png;base64,'.length), type: 'base64', @@ -81,19 +82,76 @@ router.post('/imgur/ordeal', async (req, res) => { 'ids[]': imageId, }; - if (req.body.album) { - albumData.title = req.body.album; - } + let albumJson; + 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; - } + 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', {})) { + 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 albums = await fetchImgur(req, res, 'GET', '/account/me/albums'); + if (!albums) { + return; + } + + console.log('albums', albums.data.length); + + let reject = false; + const promises = []; + for (const album of albums.data) { + promises.push(new Promise(async (res, rej) => { + if (reject) { + return reject; + } + + const images = await fetchImgur(req, res, 'GET', '/album/' + album.id + + '/images'); + + if (!images || reject) { + rej(); + return; + } + + const image = + images.data.filter(e => e.name.match(req.body.oldName))[0]; + + if (!image || reject) { + rej(); + return; + } + + reject = true; + res({ album: album, image: image }); + })); + } + + const result = await promiseAny(promises); + albumJson = { data: result.album }; + + ordealResponse.views = result.image.views; + ordealResponse.votes = await fetchImgur(req, res, 'GET', '/gallery/' + + result.image.id + '/votes'); + + if (!await fetchImgur(req, res, 'DELETE', '/image/' + result.image.id)) { + return; + } + + if (!await fetchImgur(req, res, 'PUT', '/album/' + result.album.id + + '/add', { 'ids[]': uploadJson.data.id })) { return; } } @@ -122,7 +180,7 @@ router.post('/imgur/ordeal', async (req, res) => { } } - res.json({ordealSuccess: true}); + res.json(ordealResponse); } catch(e) { console.error(e); res.status(500).json(e); diff --git a/hw7/Claudio_Maggioni/views/favourite_partial.dust b/hw7/Claudio_Maggioni/views/favourite_partial.dust index 9a75a62..d6596f8 100644 --- a/hw7/Claudio_Maggioni/views/favourite_partial.dust +++ b/hw7/Claudio_Maggioni/views/favourite_partial.dust @@ -1,9 +1,5 @@ {! vim: set ts=2 sw=2 et tw=120: !} - -

{name}

{name} {?b} @@ -35,7 +31,12 @@ formaction="/favorites/{_id}/bookmarked?_method=PUT">Add bookmark

- - +
+ +
+ + {/details} diff --git a/hw7/Claudio_Maggioni/yarn.lock b/hw7/Claudio_Maggioni/yarn.lock index bf85bbd..087d9f5 100644 --- a/hw7/Claudio_Maggioni/yarn.lock +++ b/hw7/Claudio_Maggioni/yarn.lock @@ -1830,6 +1830,11 @@ process-nextick-args@~2.0.0: resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.1.tgz#7820d9b16120cc55ca9ae7792680ae7dba6d7fe2" integrity sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag== +promise-any@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/promise-any/-/promise-any-0.2.0.tgz#7aeaafd6297698d8874cb7d3bc7c0faf89fffe8a" + integrity sha1-euqv1il2mNiHTLfTvHwPr4n//oo= + proxy-addr@~2.0.5: version "2.0.5" resolved "https://registry.yarnpkg.com/proxy-addr/-/proxy-addr-2.0.5.tgz#34cbd64a2d81f4b1fd21e76f9f06c8a45299ee34"