Permalink
Browse files

Take and upload photo widget

  • Loading branch information...
1 parent c20f775 commit 7750d4904c0d65df812a86a15d0122bcefab9b94 @Shinao committed Jun 17, 2016
Showing with 141 additions and 83 deletions.
  1. +3 −3 config.js
  2. +29 −0 public/css/style.css
  3. +5 −2 public/js/menu.js
  4. +56 −0 public/js/widget_photo.js
  5. +6 −0 public/widget_photo.html
  6. +42 −74 server.js
  7. +0 −4 widgets.js
View
@@ -9,14 +9,14 @@ config.web = {};
config.widget.cinema.url = 'http://www.allocine.fr/seance/salle_gen_csalle=C0159.html';
config.widget.cinema.refreshRateInMinutes = 60;
-config.widget.weather.appid = 'ApiKeyHere';
+config.widget.weather.appid = 'FindYourOwnKey';
config.widget.weather.url = 'http://api.openweathermap.org/data/2.5/weather?id=2988507&units=metric&appid=' + config.widget.weather.appid;
config.widget.weather.refreshRateInMinutes = 10;
config.widget.news.url = 'http://www.france24.com/en/top-stories/rss';
config.widget.news.refreshRateInMinutes = 60;
-config.widget.photo.refreshToken = 'RefreshTokenHere';
+config.widget.photo.dropboxKey = 'FindYourOwnKey';
config.web.port = 3000;
-config.web.motionUrl = 'http://localhost:3001/takePhoto';
+config.web.motionUrl = 'http://localhost:3001/takePhoto?filepath=';
module.exports = config;
View
@@ -329,4 +329,33 @@ body {
float: left;
text-align: left;
max-width: 400px;
+}
+
+#widget #photo {
+ height: 100%;
+ width: 100%;
+ margin-top: 10%;
+ align-items: center;
+ justify-content: center;
+}
+
+#widget #photo #countdown {
+ padding: 25px 100px;
+ font-size: 200px;
+ background-color: #CECECE;
+ border-radius: 2px;
+}
+
+#widget #photo #photoTaken {
+ display: none;
+ max-width: 500px;
+ max-height: 500px;
+}
+
+#widget #photo #uploadLibelle {
+ display: none;
+ padding: 5px 15px;
+ font-size: 50px;
+ background-color: #CECECE;
+ border-radius: 2px;
}
View
@@ -1,9 +1,10 @@
$(document).ready(function() {
// Add your widget here
- loadWidget("img/drive_photo.png", "widget_drive_photo.html", "callbackGesturePhoto");
+
loadWidget("img/doodlejump.png", "widget_doodlejump.html", "callbackGestureDoodleJump");
loadWidget("img/map.png", "widget_map.html", "callbackGestureMap");
loadWidget("img/cinema.png", "widget_cinema.html", "callbackGestureCinema");
+ loadWidget("img/drive_photo.png", "widget_photo.html", "callbackGesturePhoto");
loadWidget("img/news.png", "widget_news.html", "callbackGestureNews");
// Widget click event
@@ -102,8 +103,10 @@ function bringBackMainMenu() {
setTimeout(function () {
$(".screen-page-2").removeClass("pt-page-current pt-page-moveToRightFade");
$(".screen-page-1").removeClass("pt-page-moveFromLeftFade");
- }, 1000);
+ $("#widget").html("");
+ }, 800);
setCallbackGesture(callbackGestureMainMenu);
+ window.scrollTo(0, 0);
}
function smoothScrollBy(position, timeInMs) {
View
@@ -0,0 +1,56 @@
+var photofilepath = "frame.jpg";
+var photoTaken = false;
+var uploadingPhoto = false;
+function callbackGesturePhoto(gesture) {
+ if (gesture.palm && gesture.elapsedTimeWithSameGesture > 1)
+ bringBackMainMenu();
+ else if (!uploadingPhoto && photoTaken && gesture.thumbsUp && gesture.elapsedTimeWithSameGesture > 1)
+ uploadPhotoToDrive();
+}
+
+function uploadPhotoToDrive() {
+ uploadingPhoto = true;
+ $("#uploadLibelle").html("Uploading photo to Dropbox");
+ $.get("motion/uploadPhoto/" + photofilepath, function(data) {
+ $("#uploadLibelle").html("Photo succesfully uploaded");
+ }).fail(function (err) {
+ $("#uploadLibelle").html("Failed to upload photo");
+ console.log(err);
+ });
+}
+
+function displayPhoto(retryAttempt) {
+ console.log("Display photo");
+ $.get("doesFileExist/" + photofilepath, function(data) {
+ photoTaken = true;
+ $("#photoTaken").show().attr("src", photofilepath);
+ $("#countdown").hide();
+ $("#uploadLibelle").show();
+ }).fail(function (err) {
+ retryAttempt += 1;
+ if (retryAttempt > 0)
+ setTimeout(function() { displayPhoto(retryAttempt); }, 250);
+ });
+}
+
+function takePhoto() {
+ $.get("motion/takePhoto/" + photofilepath, function(data) {
+ displayPhoto(25);
+ }).fail(function (err) {
+ console.log("Motion server offline probably");
+ });;
+}
+
+var startCountdown = 1;
+$(document).ready(function() {
+ setTimeout(takePhoto, 1000 * startCountdown);
+
+ for (countdown = startCountdown; countdown >= 0; countdown--) {
+ (function(localCountdown) {
+ setTimeout(function() {
+ console.log("COUNTDOWN!" + localCountdown);
+ $("#countdown").text(localCountdown);
+ }, 1000 * startCountdown - 1000 * localCountdown);
+ })(countdown);
+ }
+});
View
@@ -0,0 +1,6 @@
+<div id="photo">
+ <div id="countdown"></div>
+ <div id="uploadLibelle">Thumbs up to upload photo to Drive</div>
+ <img id="photoTaken" src=""/>
+</div>
+<script src="js/widget_photo.js"></script>
View
116 server.js
@@ -4,6 +4,7 @@ var config = require('./config');
var app = express();
var http = require('http').Server(app);
var request = require('request');
+var fs = require('fs');
var socketIO = require('socket.io')(http);
var socketClient = null;
@@ -15,92 +16,59 @@ app.get('/', function (req, res) {
var widgets = require('./widgets');
+
+// Widgets needing infos from server (scraping infos mostly)
app.get('/weather', widgets.weather);
app.get('/news', widgets.news);
-app.get('/agario', widgets.agario);
app.get('/cinema', widgets.cinema);
// Web Socket IO for sending gestures to client
socketIO.of('/motion').on('connection', function(socket){ socketClient = socket; });
-// Forwarding between motion server and client
-app.get('/motion/gesture', function (req, res) { try { socketClient.emit('gesture', req.query); } catch(e) {} res.sendStatus(200); });
-app.get('/motion/takePhoto', function (req, res) { request(config.web.motionUrl, function(err) {}); res.sendStatus(200); });
-app.get('/motion/uploadPhoto', function (req, res) {
- 'use strict';
- var fs = require('fs');
- var google = require('googleapis');
- var drive = google.drive('v2');
- var OAuth2Client = google.auth.OAuth2;
+// Forwarding between motion server and client
+app.get('/motion/gesture', function (req, res) {
+ try {
+ socketClient.emit('gesture', req.query);
+ }
+ catch(e) {}
+ res.sendStatus(200);
+});
+app.get('/motion/takePhoto/:filepath', function (req, res) {
+ try { // Removing current photo if found
+ fs.unlinkSync("public/" + req.params.filepath);
+ } catch(e) {}
+ request(config.web.motionUrl + req.params.filepath, function(err) {
+ res.sendStatus(err ? 404 : 200);
+ });
+});
+app.get('/doesFileExist/:filepath', function (req, res) {
+ fs.access("public/" + req.params.filepath, fs.R_OK | fs.W_OK, (err) => {
+ res.sendStatus(err ? 404 : 200);
+ })
+});
- // Client ID and client secret are available at
- // https://code.google.com/apis/console
- var CLIENT_ID = "625168260868-d7khqbuva1m80s46a7rv8cglkpko7lnb.apps.googleusercontent.com";
- var CLIENT_SECRET = "cfN3dYpE5PyRI41v_r2an14J";
- var REDIRECT_URL = 'http://whatever.com/oauth';
+app.get('/motion/uploadPhoto/:filepath', function (req, res) {
+ fs.readFile("public/" + req.params.filepath, function read(err, data) {
+ if (err) {
+ console.log("Could not read photo: ", err);
+ res.sendStatus(404);
+ }
- var oauth2Client = new OAuth2Client(CLIENT_ID, CLIENT_SECRET, REDIRECT_URL);
-
-// var url = oauth2Client.generateAuthUrl({
-// access_type: 'offline', // 'online' (default) or 'offline' (gets refresh_token)
-// scope: 'https://www.googleapis.com/auth/drive' // If you only need one scope you can pass it as string
-// });
+ content = data;
+ request.put('https://api-content.dropbox.com/1/files_put/auto/' + req.params.filepath, {
+ headers: { Authorization: 'Bearer ' + config.widget.photo.dropboxKey, 'Content-Type': 'text/plain'},
+ body:content},
+ function optionalCallback (err, httpResponse, bodymsg) {
+ if (err) {
+ console.log("Could not upload to dropbox: ", err);
+ res.sendStatus(400);
+ }
-// res.send("<a href="+url+">Click here to get code</a>");
-
- oauth2Client.getToken(config.widget.photo.refreshToken, function(err, tokens) {
- // Now tokens contains an access_token and an optional refresh_token. Save them.
- if(!err) {
- oauth2Client.setCredentials(tokens);
- console.log("Token retrieved: ");
- console.log(tokens);
- fs.writeFile("./drive_access_token.txt", tokens.access_token);
- }
- else
- console.log("ERROR getToken: " + err);
-
- var saved_access_token = '';
- try { saved_access_token = fs.readFileSync('./drive_access_token.txt').toString(); }
- catch (e) { console.log("Error getting access token"); }
-
- oauth2Client.setCredentials({
- access_token: saved_access_token,
- refresh_token: config.widget.photo.refreshToken
- });
-
- // insertion example
- drive.files.insert({
- resource: {
- title: 'Test',
- mimeType: 'text/plain'
- },
- media: {
- mimeType: 'text/plain',
- body: 'Hello World updated with metadata'
- },
- auth: oauth2Client
- }, function (err, response) {
- console.log('error:', err, 'inserted:', response);
+ console.log("Uploaded photo to dropbox: ", bodymsg);
+ res.sendStatus(200);
+ });
});
});
-
- // oauth2Client.refreshAccessToken(function(err, tokens){ console.log(err); console.log("//"); console.log(tokens);});
-
-
- // drive.files.insert({
- // resource: {
- // title: 'testimage.jpg',
- // mimeType: 'image/jpg'
- // },
- // media: {
- // mimeType: 'image/jpg',
- // body: fs.createReadStream('frame.jpg') // read streams are awesome!
- // },
- // auth: oauth2Client
- // }, function (err, response) {
- // console.log('error:', err, 'inserted:', response);
- // });
-});
http.listen(config.web.port, function () {
console.log('Server listening on port %d', config.web.port);
View
@@ -44,10 +44,6 @@ module.exports.weather = function (req, res) {
res.send(weather);
}
-module.exports.agario = function (req, res) {
- res.sendFile(__dirname + '/public/agario.html');
-}
-
var movies = [];
var refreshMovies = function() {
request(config.widget.cinema.url, function (error, response, html) {

0 comments on commit 7750d49

Please sign in to comment.