server.js 8.13 KB
"use strict";

const moment = require('moment');
const process = require('process');
const async = require('async');

const express = require('express');

const AWS = require('aws-sdk');
const s3 = new AWS.S3({
	region: 'us-east-1',
	accessKeyId: 'ASIA265JP6JAKK4AAZFL',
	secretAccessKey: 'CuomIr3gEgtwPcOWSN94mC54iIMMWfXTVSFJXDUf',
	sessionToken: 'FwoGZXIvYXdzEMX//////////wEaDLD1Yk1xhWixp9ZSByK/AbDcW6LYR1EpPLNIqCteTtZtXCoIIFr7b2olxXkKyQUVQGUnf4YJVcmk8PD1/1T9O/MaJIuO0c0tAO2ir31Oa5nsc1QomKEFpAy/girMM3JML5azImFhjMKDGYahUiZWTfiP8oksDWoeEM+HjwEvWzSa5nBBoTlKxa33Gjo/15LL/oHDgN75K/fiHWAJ6Uvey0I1Lu26CjohLbEE9tQ61ymtq4GiO96DSjgSTW4gyrp5R+tn0oLH1A51oLNBfFxsKOvfxu8FMi2RufVY3HSu2JsFVyXMXkMrgDhVA5lZngj2ZW7SQx8No0vfb9zPKuHXxGKjkQY='
	});
var BUCKET = 'oss-project-image-storage';
var S3UPparam = {
	Bucket:BUCKET,
	Key:null,
	ACL:'public-read',
	Body:null
};
var S3DOWNparam = {
	Bucket:BUCKET,
	Prefix:null
};

const multer = require('multer');

// tensorflow의 data folder에 저장할 때 multer 설정
var storage_data = multer.diskStorage({
	destination: function (req, file, cb) {
		var dir = req.params.directoryName;
		cb(null, dataFolder + dir + '/');
	},
	filename: function (req, file, cb) {
		cb(null, new Date().valueOf() + "_" + file.originalname);
	}
});
var upload_data = multer({
	storage: storage_data
});

// tensorflow의 test folder에 저장할 때 multer 설정
var storage_test = multer.diskStorage({
	destination: function (req, file, cb) {
		var dir = req.params.directoryName;
		cb(null, testFolder);
	},
	filename: function (req, file, cb) {
		cb(null, "test.jpg");
	}
});
var upload_test = multer({
	storage: storage_test
});

const bodyParser = require('body-parser');
const fs = require('fs');
const path = require('path');
const pyShell = require('python-shell');

const PORT = 8080;
const HOST = '0.0.0.0';

const app = express();

const dataFolder = './tensorflow/data/';
const testFolder = './tensorflow/test/';


app.set('view engine', 'pug');
app.set('views', './views');
app.locals.pretty = true

app.use(bodyParser.urlencoded({extended:false}));


// tensorflow 학습을 완료한 시간
var LearnTime = undefined;


// Redirect Root to Home
app.get('/', (req, res) => {
	res.redirect('./home/');
});


// Main Page
app.get('/home/', (req, res) => {
	// data 폴더 목록을 읽어서 home 화면에 넘겨줌
	fs.readdir(dataFolder, function(error, filelist){
		if(error)
			console.log(error);
		res.render('home', {fileList:filelist, learntime:LearnTime});
	});
});


// Directory existence checking
app.post('/directory_check', (req, res) => {
	
	var dir = req.body.directoryName;	// 입력받은 새로운 directory name
	
	// Directory exists
	if(fs.existsSync(dataFolder + dir))
	{
		// Go back page
		res.render('error_directoryAdd');
	}
	// Directory doesn't exist
	else
	{
		// Make directory
		fs.mkdirSync(dataFolder + dir);
		console.log('Directory Create: ' + dir);
		res.redirect('/home/' + dir + '/');
	}
});


// Basic Directory Page
app.get('/home/:directoryName/', (req, res) => {
	
	// 임시로 이미지 파일명 목록을 보여주는 코드
	var directoryName = req.params.directoryName;	// 접속한 directory name
	var filelist = new Array();
	var imagelist = new Array();
	
	// read directory's file list 
	fs.readdirSync(dataFolder + directoryName).forEach(function(file, index){
		// 확장자 추출 및 이미지 파일인지 체크
		var fileType = path.extname(file);
		if(fileType == ".jpg" || fileType == ".jpeg") {
			filelist.push(file);
		}
	});
	S3DOWNparam.Prefix = directoryName + '/';
	s3.listObjects(S3DOWNparam, function (err, data) {
		if (err)
			console.log(err);
		else {
			data.Contents.forEach(function(image) {
				imagelist.push('https://' + BUCKET + '.s3.amazonaws.com/' + image.Key.replace(' ', '+'));
			});
		}
		res.render('directory', {directoryName:directoryName, fileList:filelist, imageList:imagelist});
	});
});


// Image Upload Directory Page
app.post('/home/:directoryName/upload/', upload_data.array('userImage'), (req, res) => {
	var directoryName = req.params.directoryName;
	
	req.files.forEach(function(file) {
		S3UPparam.Key = directoryName + '/' + new Date().valueOf() + "_" + file.originalname;
		S3UPparam.Body = fs.createReadStream(file.path);
		s3.upload(S3UPparam, function (err, result) {
			if (err)
				console.log(err);
		});
	});
	
	res.redirect('/home/' + directoryName + '/');
});


// Modify Directory name
app.get('/home/:directoryName/modify/', (req, res) => {
	var directoryName = req.params.directoryName;	// 본래 directory 이름
	var newName = req.query.newName;	// 입력받은 수정할 이름
	
	// exist query.newName
	if (req.query.newName) {
		// modify Directory name
		var Path = dataFolder + directoryName;
		fs.rename(Path, dataFolder + newName, function (err) {
			if (err) {
				console.log("Directory Rename error: " + err);
			} else {
				console.log("Directory Rename: " + directoryName + " -> " + newName);
			}
		});
		s3.listObjects({Bucket:BUCKET, Prefix: directoryName + '/'}, function(err, data) {
			if (data.Contents.length) {
				async.each(data.Contents, function(file, cb) {
					s3.copyObject({
						Bucket: BUCKET,
						CopySource: BUCKET + '/' + file.Key,
						Key: file.Key.replace(directoryName, newName)
					})
					.promise()
					.then(() =>
					s3.deleteObject({
						Bucket: BUCKET,
						Key: file.Key
					}).promise()
					).catch ((e) => console.error(e));
				});
			}
			s3.deleteObject({
				Bucket: BUCKET,
				Key: directoryName
			}, function(err, data) {
			if (err) console.log(err);
			});
		});
		res.redirect('/');
	}
	else {
		res.render('directoryModifyCheck', {directoryName:JSON.stringify(directoryName)});
	}
});


// Delete Directory
app.get('/home/:directoryName/delete/', (req, res) => {
	var directoryName = req.params.directoryName;
	// exist query.real
	if (req.query.real) {
		// Remove Directory and Files
		var path = dataFolder + directoryName;
		fs.readdirSync(path).forEach(function(file,index){
			var curPath = path + "/" + file;
			fs.unlinkSync(curPath);
		});
		fs.rmdirSync(path);
		// Remove S3 Directory and Files
		s3.listObjects({Bucket:BUCKET, Prefix: directoryName + '/'}, function(err, data) {
			if (data.Contents.length) {
				async.each(data.Contents, function(file, cb) {
					s3.deleteObject({
						Bucket: BUCKET,
						Key: file.Key
					}, function(err, data) {
					if (err) console.log(err);
					});
				});
			}
		});
		
		console.log('Directory Delete: ' + directoryName);
		res.redirect('/');
	}
	else {
		res.render('directoryDeleteCheck', {directoryName:JSON.stringify(directoryName)});
	}
});


// Image Test Page
app.post('/test', upload_test.single('TestImage'), (req, res) => {
	var results = new Array();
	
	console.log("Test Start");
	process.chdir('./tensorflow/');	// move working directory
	
	// retrain_run_inference.py로 test
	pyShell.PythonShell.run('retrain_run_inference.py', null, function (err, result) {
		if (err) {
			console.log('Test error: '+ err);
		}
		else {
			var strArr = result.toString().split('\n');	// result를 줄바꿈 기준으로 자름
			// 결과만 results에 저장
			strArr.forEach(function(str) {
				if (str.indexOf('score') > -1) {
					str = str.split('\\n').join('');
					results = str.split(',');
					for(var i = 0; i < results.length; i++){
						results[i] = results[i].substring(1);
					}
				}
			});
		}
		process.chdir('../');	// move working directory
		console.log(results);
		console.log("Test Complete");
		res.render('testResult', {result:results});
	});
});


// Image Learning
app.get('/imageLearning', (req, res) => {
	var results = new Array();
	var tmp = LearnTime;
	
	res.redirect('/home/');
	
	console.log("Learning Start");
	process.chdir('./tensorflow/');	// move working directory
	
	// retrain.py로 학습
	LearnTime = "학습 중...";
	pyShell.PythonShell.run('retrain.py', null, function (err, result) {
		if (err) {
			console.log('Learning error: '+ err);
			LearnTime = tmp + ', error: 다시 학습 버튼을 눌러주세요';
		}
		else {
			LearnTime = moment().format('YYYY-MM-DD HH:mm:ss');	// 학습 완료한 시간 저장
			console.log("Learning Complete");
		}
	});
	process.chdir('../');	// move working directory
});


app.listen(PORT, HOST);
console.log('Running on http://${HOST}:${POST}');