diff --git a/hw7/Claudio_Maggioni/app.js b/hw7/Claudio_Maggioni/app.js
index a7aee92..f674478 100644
--- a/hw7/Claudio_Maggioni/app.js
+++ b/hw7/Claudio_Maggioni/app.js
@@ -89,4 +89,15 @@ eventBus.on('favorite.deleted', (event) => {
io.emit('favorite.deleted', event);
});
+const { exec } = require('child_process');
+const client = '3710c666dbec94e';
+const imgURL = `https://api.imgur.com/oauth2/authorize?client_id=${client}` +
+ "&response_type=token";
+
+exec(`open '${imgURL}' || xdg-open ${imgURL}`, (err) => {
+ if (err) {
+ console.error(err);
+ }
+});
+
module.exports = app;
diff --git a/hw7/Claudio_Maggioni/package.json b/hw7/Claudio_Maggioni/package.json
index b25c979..7e373b3 100644
--- a/hw7/Claudio_Maggioni/package.json
+++ b/hw7/Claudio_Maggioni/package.json
@@ -23,10 +23,12 @@
"debug": "^3.1.0",
"dustjs-linkedin": "^2.7.5",
"express": "^4.16.2",
+ "form-data": "^3.0.0",
"klei-dust": "^1.0.0",
"method-override": "^3.0.0",
"mongoose": "^5.7.7",
"morgan": "^1.9.0",
+ "node-fetch": "^2.6.0",
"request": "^2.88.0",
"socket.io": "^2.3.0",
"supertest": "^3.0.0"
diff --git a/hw7/Claudio_Maggioni/public/js/views.js b/hw7/Claudio_Maggioni/public/js/views.js
index 7581c0d..9abe443 100644
--- a/hw7/Claudio_Maggioni/public/js/views.js
+++ b/hw7/Claudio_Maggioni/public/js/views.js
@@ -1,5 +1,6 @@
-(function(dust){dust.register("favourites",body_0);function body_0(chk,ctx){return chk.w("
").x(ctx.get(["bookmarked"], false),ctx,{"else":body_1,"block":body_2},{}).w("").x(ctx.get(["bookmarked"], false),ctx,{"else":body_3,"block":body_4},{}).s(ctx.get(["favs"], false),ctx,{"else":body_5,"block":body_6},{}).w("");}body_0.__dustBody=!0;function body_1(chk,ctx){return chk.w("Favourites");}body_1.__dustBody=!0;function body_2(chk,ctx){return chk.w("Bookmarked");}body_2.__dustBody=!0;function body_3(chk,ctx){return chk.w("Favourites
");}body_3.__dustBody=!0;function body_4(chk,ctx){return chk.w("Bookmarked
");}body_4.__dustBody=!0;function body_5(chk,ctx){return chk.w("No favourites.");}body_5.__dustBody=!0;function body_6(chk,ctx){return chk.w("").p("favourite_partial",ctx,ctx,{"name":ctx.get(["name"], false),"dataURL":ctx.get(["dataURL"], false),"_id":ctx.get(["_id"], false),"bookmarked":ctx.get(["bookmarked"], false),"details":"true"}).w("
");}body_6.__dustBody=!0;return body_0}(dust));
(function(dust){dust.register("500",body_0);function body_0(chk,ctx){return chk.w("Error 500
").f(ctx.get(["err"], false),ctx,"h").w("
");}body_0.__dustBody=!0;return body_0}(dust));
-(function(dust){dust.register("index",body_0);function body_0(chk,ctx){return chk.w("OO-JS Exercise - Web Atelier 2017OO-JS Exercise: Canvas
");}body_0.__dustBody=!0;return body_0}(dust));
-(function(dust){dust.register("favourite_partial",body_0);function body_0(chk,ctx){return chk.w("").f(ctx.get(["name"], false),ctx,"h").w("
").x(ctx.get(["b"], false),ctx,{"block":body_1},{}).x(ctx.get(["details"], false),ctx,{"else":body_2,"block":body_5},{});}body_0.__dustBody=!0;function body_1(chk,ctx){return chk.w("Bookmarked
");}body_1.__dustBody=!0;function body_2(chk,ctx){return chk.w("");}body_2.__dustBody=!0;function body_3(chk,ctx){return chk.w("");}body_3.__dustBody=!0;function body_4(chk,ctx){return chk.w("");}body_4.__dustBody=!0;function body_5(chk,ctx){return chk.w("Details");}body_5.__dustBody=!0;return body_0}(dust));
(function(dust){dust.register("favourite",body_0);function body_0(chk,ctx){return chk.w("").f(ctx.get(["name"], false),ctx,"h").w("").p("favourite_partial",ctx,ctx,{}).w("Favourites list");}body_0.__dustBody=!0;return body_0}(dust));
+(function(dust){dust.register("favourite_partial",body_0);function body_0(chk,ctx){return chk.w("").f(ctx.get(["name"], false),ctx,"h").w("
").x(ctx.get(["b"], false),ctx,{"block":body_1},{}).x(ctx.get(["details"], false),ctx,{"else":body_2,"block":body_5},{});}body_0.__dustBody=!0;function body_1(chk,ctx){return chk.w("Bookmarked
");}body_1.__dustBody=!0;function body_2(chk,ctx){return chk.w("");}body_2.__dustBody=!0;function body_3(chk,ctx){return chk.w("");}body_3.__dustBody=!0;function body_4(chk,ctx){return chk.w("");}body_4.__dustBody=!0;function body_5(chk,ctx){return chk.w("Details");}body_5.__dustBody=!0;return body_0}(dust));
+(function(dust){dust.register("favourites",body_0);function body_0(chk,ctx){return chk.w("").x(ctx.get(["bookmarked"], false),ctx,{"else":body_1,"block":body_2},{}).w("").x(ctx.get(["bookmarked"], false),ctx,{"else":body_3,"block":body_4},{}).s(ctx.get(["favs"], false),ctx,{"else":body_5,"block":body_6},{}).w("");}body_0.__dustBody=!0;function body_1(chk,ctx){return chk.w("Favourites");}body_1.__dustBody=!0;function body_2(chk,ctx){return chk.w("Bookmarked");}body_2.__dustBody=!0;function body_3(chk,ctx){return chk.w("Favourites
");}body_3.__dustBody=!0;function body_4(chk,ctx){return chk.w("Bookmarked
");}body_4.__dustBody=!0;function body_5(chk,ctx){return chk.w("No favourites.");}body_5.__dustBody=!0;function body_6(chk,ctx){return chk.w("").p("favourite_partial",ctx,ctx,{"name":ctx.get(["name"], false),"dataURL":ctx.get(["dataURL"], false),"_id":ctx.get(["_id"], false),"bookmarked":ctx.get(["bookmarked"], false),"details":"true"}).w("
");}body_6.__dustBody=!0;return body_0}(dust));
+(function(dust){dust.register("index",body_0);function body_0(chk,ctx){return chk.w("OO-JS Exercise - Web Atelier 2017OO-JS Exercise: Canvas
");}body_0.__dustBody=!0;return body_0}(dust));
+(function(dust){dust.register("server_side",body_0);function body_0(chk,ctx){return chk.s(ctx.get(["favs"], false),ctx,{"block":body_1},{});}body_0.__dustBody=!0;function body_1(chk,ctx){return chk.w("").p("favourite_partial",ctx,ctx,{"name":ctx.get(["name"], false),"dataURL":ctx.get(["dataURL"], false),"_id":ctx.get(["_id"], false),"bookmarked":ctx.get(["bookmarked"], false)}).w("
");}body_1.__dustBody=!0;function body_2(chk,ctx){return chk.w("bookmarked");}body_2.__dustBody=!0;return body_0}(dust));
diff --git a/hw7/Claudio_Maggioni/public/scripts/app.js b/hw7/Claudio_Maggioni/public/scripts/app.js
index 10b01c6..71bcb77 100644
--- a/hw7/Claudio_Maggioni/public/scripts/app.js
+++ b/hw7/Claudio_Maggioni/public/scripts/app.js
@@ -14,8 +14,41 @@ class App {
socketSessionId = null;
registerFavoriteEvents(_id, dom) {
- const form = dom.querySelector('form');
+ const imgurForm = dom.querySelector('form.favorites');
+
+ dom.querySelector('button.imgur').onclick = () => {
+ imgurForm.classList.toggle('hidden');
+ };
+
+ imgurForm.onsubmit = e => {
+ imgurForm.classList.remove('ok');
+ imgurForm.classList.remove('err');
+ e.preventDefault();
+ const data = new FormData(imgurForm);
+
+ const obj = {
+ dataURL: data.get('dataURL'),
+ name: dom.querySelector('form.data input[name=name]').value,
+ album: data.get('album'),
+ tags: data.get('tags'),
+ favorites: data.get('favorites')
+ };
+
+ doJSONRequest('POST', '/imgur/ordeal', {}, obj)
+ .then(e => {
+ if (e.ordealSuccess === true) {
+ imgurForm.classList.add('ok');
+ } else {
+ imgurForm.classList.add('err');
+ }
+ }).catch(e => {
+ console.error(e);
+ imgurForm.classList.add('err');
+ });
+ };
+
+ const form = dom.querySelector('form.data');
const delay = (f, ...args) => {
const execute = (f, ...args) => {
@@ -224,8 +257,6 @@ class App {
nameFilter.onkeyup = onSearch;
bookmarkFilter.onclick = onSearch;
-
-
if (typeof conf.buttons === 'object' && conf.buttons) {
this.buttons = {}
for (const b of ['clear', 'undo', 'camera'])
diff --git a/hw7/Claudio_Maggioni/routes/root/router.js b/hw7/Claudio_Maggioni/routes/root/router.js
index 170bcc4..e76b412 100644
--- a/hw7/Claudio_Maggioni/routes/root/router.js
+++ b/hw7/Claudio_Maggioni/routes/root/router.js
@@ -7,6 +7,8 @@ const router = express.Router();
const mongoose = require('mongoose');
const Favorite = mongoose.model('Favorite');
+const fetch = require('node-fetch');
+const querystring = require('querystring');
const { error } = require('../utils');
@@ -15,10 +17,117 @@ router.get('/', (req, res) => {
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(`
+ `);
+ }
+});
+
+async function fetchImgur(req, res, method, url, body) {
+ const endpoint = 'https://api.imgur.com/3';
+
+ const uploadRes = 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)
+ });
+
+ const uploadJson = await uploadRes.json();
+
+ if (Math.floor(uploadJson.status / 100) != 2) {
+ res.status(uploadJson.status).json(uploadJson);
+ return false;
+ }
+
+ console.log(url, uploadJson);
+
+ return uploadJson;
+}
+
+router.post('/imgur/ordeal', async (req, res) => {
+ try {
+ const uploadData = {
+ image: req.body.dataURL.substring('data:image/png;base64,'.length),
+ type: 'base64',
+ 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.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;
+ }
+ }
+
+ if (!await fetchImgur(req, res, 'POST', '/gallery/album/' +
+ albumJson.data.id, { title: req.body.album ? req.body.album :
+ req.body.name })) {
+ return;
+ }
+
+ if (req.body.tags) {
+ const tagsData = {
+ 'tags': req.body.tags
+ };
+
+ if (!await fetchImgur(req, res, 'POST', '/gallery/tags/' +
+ albumJson.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({ordealSuccess: true});
+ } catch(e) {
+ console.error(e);
+ res.status(500).json(e);
+ }
+});
+
/** router for /root */
module.exports = router;
diff --git a/hw7/Claudio_Maggioni/views/favourite_partial.dust b/hw7/Claudio_Maggioni/views/favourite_partial.dust
index bffde38..9a75a62 100644
--- a/hw7/Claudio_Maggioni/views/favourite_partial.dust
+++ b/hw7/Claudio_Maggioni/views/favourite_partial.dust
@@ -1,5 +1,9 @@
{! vim: set ts=2 sw=2 et tw=120: !}
+
+
{name}
{?b}
@@ -10,10 +14,11 @@
{?details}
Details
{:else}
-
+
{/details}
diff --git a/hw7/Claudio_Maggioni/yarn.lock b/hw7/Claudio_Maggioni/yarn.lock
index 5ebbe3e..bf85bbd 100644
--- a/hw7/Claudio_Maggioni/yarn.lock
+++ b/hw7/Claudio_Maggioni/yarn.lock
@@ -360,7 +360,7 @@ collection-visit@^1.0.0:
map-visit "^1.0.0"
object-visit "^1.0.0"
-combined-stream@^1.0.6, combined-stream@~1.0.6:
+combined-stream@^1.0.6, combined-stream@^1.0.8, combined-stream@~1.0.6:
version "1.0.8"
resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f"
integrity sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==
@@ -816,6 +816,15 @@ form-data@^2.3.1:
combined-stream "^1.0.6"
mime-types "^2.1.12"
+form-data@^3.0.0:
+ version "3.0.0"
+ resolved "https://registry.yarnpkg.com/form-data/-/form-data-3.0.0.tgz#31b7e39c85f1355b7139ee0c647cf0de7f83c682"
+ integrity sha512-CKMFDglpbMi6PyN+brwB9Q/GOw0eAnsrEZDgcsH5Krhz5Od/haKHAX0NmQfha2zPPz0JpWzA7GJHGSnvCRLWsg==
+ dependencies:
+ asynckit "^0.4.0"
+ combined-stream "^1.0.8"
+ mime-types "^2.1.12"
+
form-data@~2.3.2:
version "2.3.3"
resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.3.3.tgz#dcce52c05f644f298c6a7ab936bd724ceffbf3a6"
@@ -1610,6 +1619,11 @@ negotiator@0.6.2:
resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.2.tgz#feacf7ccf525a77ae9634436a64883ffeca346fb"
integrity sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw==
+node-fetch@^2.6.0:
+ version "2.6.0"
+ resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.0.tgz#e633456386d4aa55863f676a7ab0daa8fdecb0fd"
+ integrity sha512-8dG4H5ujfvFiqDmVu9fQ5bOHUC15JMjMY/Zumv26oOvvVJjM67KF8koCWIabKQ1GJIa9r2mMZscBq/TbdOcmNA==
+
node-pre-gyp@^0.12.0:
version "0.12.0"
resolved "https://registry.yarnpkg.com/node-pre-gyp/-/node-pre-gyp-0.12.0.tgz#39ba4bb1439da030295f899e3b520b7785766149"