262 lines
		
	
	
		
			7.8 KiB
		
	
	
	
		
			HTML
		
	
	
	
	
	
			
		
		
	
	
			262 lines
		
	
	
		
			7.8 KiB
		
	
	
	
		
			HTML
		
	
	
	
	
	
<!--
 | 
						|
	Copyright (C) 2021 Thomas Van Acker
 | 
						|
 | 
						|
	This program is free software: you can redistribute it and/or modify it under
 | 
						|
	the terms of the GNU General Public License as published by the Free Software
 | 
						|
	Foundation, either version 3 of the License, or (at your option) any later
 | 
						|
	version.
 | 
						|
 | 
						|
	This program is distributed in the hope that it will be useful, but WITHOUT
 | 
						|
	ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 | 
						|
	FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
 | 
						|
 | 
						|
	You should have received a copy of the GNU General Public License along with
 | 
						|
	this program. If not, see <https://www.gnu.org/licenses/>.
 | 
						|
 | 
						|
	This project is hosted on https://git.bitscuit.be/bitscuit/Fawkes
 | 
						|
-->
 | 
						|
<html>
 | 
						|
	<head>
 | 
						|
		<title>Fawkes</title>
 | 
						|
 | 
						|
		<meta name="viewport" content="width=device-width, initial-scale=1">
 | 
						|
 | 
						|
		<link href="https://fonts.googleapis.com/css?family=Raleway:400,300,600" rel="stylesheet" type="text/css">
 | 
						|
 | 
						|
		<link href="css/normalize.css" rel="stylesheet">
 | 
						|
		<link href="css/skeleton.css" rel="stylesheet">
 | 
						|
		<link href="css/extra.css" rel="stylesheet">
 | 
						|
		<link href="css/fontawesome/css/all.css" rel="stylesheet">
 | 
						|
 | 
						|
	</head>
 | 
						|
	<body style="padding-top: 10px;">
 | 
						|
		<div id="main" class="container" style="text-align: center;">
 | 
						|
			<h1>Fawkes</h1>
 | 
						|
			<p>Protect your images from facial recognition.</p>
 | 
						|
		</div>
 | 
						|
 | 
						|
		<div id="manual-area" class="container" style="text-align: center;">
 | 
						|
			<p>Please upload the images you want to protect.</p>
 | 
						|
			<p>The table below shows the status for each image you've uploaded. You can select the files you want to protect using the <i>Browse</i> and <i>Upload</i> buttons below.</p>
 | 
						|
		</div>
 | 
						|
 | 
						|
		<div id="upload-area" class="container">
 | 
						|
			<div class="row">
 | 
						|
				<div class="twelve columns">
 | 
						|
					<label for="input-file">Your Image</label>
 | 
						|
					<input class="u-full-width" type="file" id="input-file">
 | 
						|
				</div>
 | 
						|
			</div>
 | 
						|
			<button id="button-upload" class="button button-primary"><i class="fas fa-upload"></i>   Upload</button>
 | 
						|
		</div>
 | 
						|
 | 
						|
		<div id="table-area" class="container">
 | 
						|
			<table id="table-images" class="u-full-width">
 | 
						|
				<thead>
 | 
						|
					<tr>
 | 
						|
						<th>Image Name</th>
 | 
						|
						<th>Status</th>
 | 
						|
					</tr>
 | 
						|
				</thead>
 | 
						|
				<tbody>
 | 
						|
				</tbody>
 | 
						|
			</table>
 | 
						|
			
 | 
						|
			<p id="text-no-images" style="text-align: center;">You haven't uploaded any images yet.</p>
 | 
						|
 | 
						|
			<button class="button button-primary" id="button-start"><i class="fas fa-check"></i>   Start Fawkes</button>
 | 
						|
		</div>
 | 
						|
 | 
						|
		<div id="download-area" class="container" style="text-align: center;">
 | 
						|
		</div>
 | 
						|
 | 
						|
		<div class="footer">
 | 
						|
			<p>Many thanks to the people who made <a href="http://sandlab.cs.uchicago.edu/fawkes/">Fawkes</a>!<br/>Copyright © 2021 Thomas Van Acker<br/>Project hosted on <a target="_blank" href="https://git.bitscuit.be/bitscuit/Fawkes">Gitscuit</a></p>
 | 
						|
		</div>
 | 
						|
 | 
						|
 | 
						|
<!-- Socket.io stuff -->
 | 
						|
<script src="/socket.io/socket.io.js"></script>
 | 
						|
<script>
 | 
						|
 | 
						|
// Vars
 | 
						|
var files = {};
 | 
						|
 | 
						|
// Start socket.io
 | 
						|
var socket = io();
 | 
						|
 | 
						|
// Init listeners
 | 
						|
document.getElementById("button-upload").addEventListener("click", function(){
 | 
						|
	if(document.getElementById("input-file").files.length != 0){
 | 
						|
		var file = document.getElementById("input-file").files[0];
 | 
						|
 | 
						|
		// Add file to files list
 | 
						|
		var id = Date.now();
 | 
						|
		files[id] = {
 | 
						|
			file: file,
 | 
						|
			uploading: true,
 | 
						|
			error: false
 | 
						|
		};
 | 
						|
 | 
						|
		// Add file to table
 | 
						|
		var table = document.getElementById("table-images").getElementsByTagName("tbody")[0];
 | 
						|
		var row = "";
 | 
						|
		row += "<tr id='row-"+id+"'>";
 | 
						|
		row += "<td>"+file.name+"</td>";
 | 
						|
		row += "<td id='status-"+id+"'><i class='fas fa-spinner fa-pulse'></i>   Initializing Upload</td>";
 | 
						|
		row += "</tr>";
 | 
						|
		table.innerHTML += row;
 | 
						|
 | 
						|
		document.getElementById("text-no-images").style.display = "none";
 | 
						|
 | 
						|
		// Send request to server
 | 
						|
		socket.emit("FILE_START", {name:id, length:file.size});
 | 
						|
 | 
						|
		// Reset file input
 | 
						|
		document.getElementById("input-file").value = "";
 | 
						|
 | 
						|
	}else{
 | 
						|
		// No file selected
 | 
						|
		alert("Please select a file using the 'Browse' button.");
 | 
						|
	}
 | 
						|
});
 | 
						|
 | 
						|
socket.on("FILE_ERROR", function(data){
 | 
						|
	// When error while uploading
 | 
						|
	files[data.name].uploading = false;
 | 
						|
	files[data.name].error = true;
 | 
						|
	document.getElementById("status-"+data.name).innerHTML = "<i class='fas fa-exclamation-triangle'></i>   Upload Error";
 | 
						|
	document.getElementById("status-"+data.name).title = data.error;
 | 
						|
});
 | 
						|
 | 
						|
socket.on("FILE_ACK", function(data){
 | 
						|
	// When can send next file segment
 | 
						|
	var file = files[data.name];
 | 
						|
	var offset = data.nextSegment * 100000;
 | 
						|
	var fileSegment = file.file.slice(offset, Math.min(offset + 100000, file.file.size));
 | 
						|
	var fileReader = new FileReader();
 | 
						|
	fileReader.onload = function(event){
 | 
						|
		socket.emit("FILE_DATA", {name:data.name, data:event.target.result, segment:data.nextSegment});
 | 
						|
	};
 | 
						|
	fileReader.readAsBinaryString(fileSegment);
 | 
						|
 | 
						|
	// Update status
 | 
						|
	document.getElementById("status-"+data.name).innerHTML = "<i class='fas fa-spinner fa-pulse'></i>   Uploading ("+Math.floor(100*data.nextSegment/data.numSegments)+"%)";
 | 
						|
});
 | 
						|
 | 
						|
socket.on("FILE_DONE", function(data){
 | 
						|
	// File upload done
 | 
						|
	files[data.name].uploading = false;
 | 
						|
	document.getElementById("status-"+data.name).innerHTML = "<i class='fas fa-check'></i>   Upload Complete";
 | 
						|
});
 | 
						|
 | 
						|
document.getElementById("button-start").addEventListener("click", function(){
 | 
						|
	// When start button clicked
 | 
						|
 | 
						|
	// Check if all files uploaded
 | 
						|
	var num = 0;
 | 
						|
	for(let id in files){
 | 
						|
		if(files[id].uploading){
 | 
						|
			alert("Not all files have been uploaded!");
 | 
						|
			return;
 | 
						|
		}else if(!files[id].error){
 | 
						|
			num++;
 | 
						|
		}
 | 
						|
	}
 | 
						|
	if(num == 0){
 | 
						|
		alert("You haven't uploaded any files yet!");
 | 
						|
		return;
 | 
						|
	}
 | 
						|
 | 
						|
	// Disable button and upload
 | 
						|
	document.getElementById("button-start").style.display = "none";
 | 
						|
	document.getElementById("upload-area").style.display = "none";
 | 
						|
 | 
						|
	// Display new manual text
 | 
						|
	var man = "";
 | 
						|
	man += "<p>Please wait while Fawkes processes your images. This might take a while.</p>";
 | 
						|
	document.getElementById("manual-area").innerHTML = man;
 | 
						|
 | 
						|
	// Send server request to start Fawkes
 | 
						|
	socket.emit("FAWKES_START");
 | 
						|
});
 | 
						|
 | 
						|
socket.on("FAWKES_STARTED", function(){
 | 
						|
	// Update all states
 | 
						|
	for(let id in files){
 | 
						|
		if(!files[id].uploading && !files[id].error){
 | 
						|
			document.getElementById("status-"+id).innerHTML = "<i class='fas fa-hourglass-half'></i>   In Queue";
 | 
						|
		}
 | 
						|
	}
 | 
						|
});
 | 
						|
 | 
						|
socket.on("FAWKES_STATE", function(data){
 | 
						|
	// Update state
 | 
						|
	if(data.face > data.numFaces){
 | 
						|
		document.getElementById("status-"+data.name).innerHTML = "<i class='fas fa-check'></i>   Processing Complete";
 | 
						|
	}else if(data.numFaces == 0){
 | 
						|
		document.getElementById("status-"+data.name).innerHTML = "<i class='fas fa-check'></i>   No Faces Detected";
 | 
						|
	}else{
 | 
						|
		document.getElementById("status-"+data.name).innerHTML = "<i class='fas fa-spinner fa-pulse'></i>   Processing Faces ("+data.face+"/"+data.numFaces+")";
 | 
						|
	}
 | 
						|
});
 | 
						|
 | 
						|
socket.on("FAWKES_DONE", function(data){
 | 
						|
	// When fawkes exited
 | 
						|
	if(data.success){
 | 
						|
		// Download ready
 | 
						|
		var page = "";
 | 
						|
		page += "<h5><i class='fas fa-check'></i>   Processing Complete</h5>";
 | 
						|
		page += "<p>Your images have been protected!</p>";
 | 
						|
		page += "<a class='button button-primary' href='"+data.downloadUrl+"' target='_blank'><i class='fas fa-download'></i>   Download</a>";
 | 
						|
		document.getElementById("download-area").innerHTML = page;
 | 
						|
		document.getElementById("table-area").style.display = "none";
 | 
						|
		document.getElementById("manual-area").style.display = "none";
 | 
						|
 | 
						|
	}else{
 | 
						|
		// Error
 | 
						|
		var page = "";
 | 
						|
		page += "<h5><i class='fas fa-exclamation-triangle'></i>   Processing Failed</h5>";
 | 
						|
		page += "<p>"+data.message+"</p>";
 | 
						|
		document.getElementById("download-area").innerHTML = page;
 | 
						|
		document.getElementById("table-area").style.display = "none";
 | 
						|
		document.getElementById("manual-area").style.display = "none";
 | 
						|
	}
 | 
						|
});
 | 
						|
 | 
						|
</script>
 | 
						|
 | 
						|
 | 
						|
	</body>
 | 
						|
</html>
 | 
						|
 | 
						|
 | 
						|
 | 
						|
 | 
						|
 | 
						|
 | 
						|
 | 
						|
 | 
						|
 | 
						|
 | 
						|
 | 
						|
 | 
						|
 | 
						|
 | 
						|
 | 
						|
 | 
						|
 | 
						|
 | 
						|
 | 
						|
 | 
						|
 | 
						|
 | 
						|
 | 
						|
 | 
						|
 | 
						|
 | 
						|
 | 
						|
 | 
						|
 | 
						|
 |