Fawkes/html/index.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>&nbsp;&nbsp;&nbsp;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>&nbsp;&nbsp;&nbsp;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 &copy; 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>&nbsp;&nbsp;&nbsp;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>&nbsp;&nbsp;&nbsp;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>&nbsp;&nbsp;&nbsp;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>&nbsp;&nbsp;&nbsp;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>&nbsp;&nbsp;&nbsp;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>&nbsp;&nbsp;&nbsp;Processing Complete";
}else if(data.numFaces == 0){
document.getElementById("status-"+data.name).innerHTML = "<i class='fas fa-check'></i>&nbsp;&nbsp;&nbsp;No Faces Detected";
}else{
document.getElementById("status-"+data.name).innerHTML = "<i class='fas fa-spinner fa-pulse'></i>&nbsp;&nbsp;&nbsp;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>&nbsp;&nbsp;&nbsp;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>&nbsp;&nbsp;&nbsp;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>&nbsp;&nbsp;&nbsp;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>