New and updated version of old code.

This commit is contained in:
2024-05-15 21:24:05 +02:00
commit cc1038047e
11 changed files with 448 additions and 0 deletions

2
README.md Normal file
View File

@@ -0,0 +1,2 @@
# saneAdmin

25
api/discoverScanners.php Normal file
View File

@@ -0,0 +1,25 @@
<?php
function discoverScanners()
{
$scannersList = shell_exec('sudo scanimage -f "%d|%v %m"');
if($scannersList != "")
{
session_start();
$_SESSION["ScannersList"][0] = explode('|', $scannersList);
return true;
}
else return false;
}
// TODO / DEBUG - Fix this function
if(discoverScanners() === true) echo "OK";
else echo "Failed";
// TEST code
// session_start();
// $_SESSION["ScannersList"][0] = [ "xerox_mfp:libusb:003:010", "Samsung M2070" ];
// echo "OK";
?>

26
api/imageDownload.php Normal file
View File

@@ -0,0 +1,26 @@
<?php
if (isset($_GET['filename']))
{
require("../include/appConfig.php");
// Strip only file name form user string so he do not download system configs or whatnot
$file = $appConfig['imagesLocation'].basename($_GET['filename']);
if(!file_exists($file)) die('404 - File not found.');
else
{
// Set appropriate headers
header("Cache-Control: private");
header("Content-Description: File Transfer");
header("Content-Disposition: attachment; filename=".basename($_GET['filename']));
header("Content-Type: ".mime_content_type($file));
header("Content-Transfer-Encoding: binary");
// Read the file from disk
readfile($file);
}
}
else echo "404 - File name not found.";
?>

9
api/rediscover.php Normal file
View File

@@ -0,0 +1,9 @@
<?php
session_start();
session_unset();
session_destroy();
header("Location: ../index.php");
exit;
?>

126
api/scan.php Normal file
View File

@@ -0,0 +1,126 @@
<?php
require("../include/appConfig.php");
session_start();
////
//
/// Functions
//
////
function generateRandomString($length = 10)
{
$characters = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
$charactersLength = strlen($characters);
$randomString = '';
for ($i = 0; $i < $length; $i++)
{
$randomString .= $characters[rand(0, $charactersLength - 1)];
}
return $randomString;
}
function checkInput()
{
global $appConfig;
$checkOK = true;
if (isset($_GET['outputImageResolution']))
{
$found = false;
foreach ($appConfig['outputImageResolution'] as $item)
{
if($item[0] == $_GET['outputImageResolution']) $found = true;
}
if(!$found) $checkOK = false;
}
else $checkOK = false;
if (isset($_GET['outputImageColorDepth']))
{
$found = false;
foreach ($appConfig['outputImageColorDepth'] as $item)
{
if($item[0] == $_GET['outputImageColorDepth']) $found = true;
}
if(!$found) $checkOK = false;
}
else $checkOK = false;
if(isset($_GET['outputFileFormat']))
{
$found = false;
foreach ($appConfig['outputImageFormats'] as $item)
{
if($item[0] == $_GET['outputFileFormat']) $found = true;
}
if(!$found) $checkOK = false;
}
else $checkOK = false;
if (isset($_GET['inputPageSize']))
{
$found = false;
foreach ($appConfig['inputPageSizes'] as $item)
{
if($item[0] == $_GET['inputPageSize']) $found = true;
}
if(!$found) $checkOK = false;
}
else $checkOK = false;
if (isset($_GET['deviceID']))
{
$found = false;
foreach ($_SESSION['ScannersList'] as $item)
{
if($item[0] == $_GET['deviceID']) $found = true;
}
if(!$found) $checkOK = false;
}
else $checkOK = false;
return $checkOK;
}
function getNewFileName()
{
return 'scan-'.date('Ymd').'-'.generateRandomString().'.'.$_GET['outputFileFormat'];
}
////
//
/// Logic
//
////
if(checkInput() !== true)
{
echo "400 - Bad request";
http_response_code(400);
exit;
}
//Generate file name for scanned image
$filename = getNewFileName();
$scanCommand = "sudo scanimage --device-name ".$_GET['deviceID']." --format ".$_GET['outputFileFormat']." --resolution ".$_GET['outputImageResolution']." --mode ".$_GET['outputImageColorDepth']." > ".$appConfig['imagesLocation'].$filename;
////
//
/// Scanning start
//
////
//Prepare directory for scanned image
if(!is_dir($appConfig['imagesLocation'])) mkdir($appConfig['imagesLocation'], 777, true);
//Scan image
shell_exec($scanCommand);
//Output scanned image name indicating that scanning finished
echo $filename;
?>

BIN
assets/placeholderImage.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

BIN
assets/placeholderImage.xcf Normal file

Binary file not shown.

31
include/appConfig.php Normal file
View File

@@ -0,0 +1,31 @@
<?php
$appConfig['imagesLocation'] = "/mnt/pool1/smb/Scanner/";
// Defaults for Samsung M2070
$appConfig['outputImageResolution'] = array(
[ "75", "75 DPI", false ],
[ "100", "100 DPI", false ],
[ "150", "150 DPI", false ],
[ "200", "200 DPI", false ],
[ "300", "300 DPI", true ],
[ "600", "600 DPI", false ]
);
$appConfig['outputImageColorDepth'] = array(
[ "Lineart", "Lineart", false ],
[ "Halftone", "Halftone", false ],
[ "Gray", "Gray", true ],
[ "Color", "Color", false ]
);
$appConfig['outputImageFormats'] = array(
[ "pnm", "PNM", false ],
[ "tiff", "TIFF(Image)", false ],
[ "png", "PNG(Image)", true ],
[ "jpeg", "JPEG(Image)", false ],
[ "pdf", "PDF", false ]
);
$appConfig['inputPageSizes'] = array(
[ "a4", "A4", true ]
);
?>

35
index.php Normal file
View File

@@ -0,0 +1,35 @@
<?php
session_start();
if (isset($_SESSION["ScannersList"]))
{
header("Location: interface.php");
exit;
}
?>
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>saneAdmin</title>
<script src="js/appControl.js"></script>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-QWTKZyjpPEjISv5WaRU9OFeRpok6YctnYmDr5pNlyT2bRjXh0JMhjY6hW+ALEwIH" crossorigin="anonymous">
</head>
<body>
<div class="container text-center">
<h1>saneAdmin</h1>
<div id="scannerSearchProgress" class="progress mt-5" role="progressbar">
<div class="progress-bar" style="width: 0%"></div>
</div>
<p class="mt-2">Searching for scanners...</p>
</div>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js" integrity="sha384-YvpcrYf0tY3lHB60NNkmXc5s9fDVZLESaAA55NDzOxhy9GkcIdslK1eN7N6jIeHz" crossorigin="anonymous"></script>
</body>
</html>

115
interface.php Normal file
View File

@@ -0,0 +1,115 @@
<?php
session_start();
if (!isset($_SESSION["ScannersList"]))
{
header("Location: interface.php");
exit;
}
require("include/appConfig.php");
?>
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>saneAdmin</title>
<script src="js/appControl.js"></script>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-QWTKZyjpPEjISv5WaRU9OFeRpok6YctnYmDr5pNlyT2bRjXh0JMhjY6hW+ALEwIH" crossorigin="anonymous">
</head>
<body>
<div class="container text-center">
<h1><heavy>saneAdmin</heavy> - web based scanner control</h1>
</div>
<div class="container mt-5">
<div class="row">
<div class="col">
<p class="fw-medium">Settings</p>
<hr>
<div class="mb-3">
<label for="deviceIDFormSelect" class="form-label">Device:</label>
<select class="form-select" id="deviceIDFormSelect" aria-label="Device ID select">
<?php
foreach($_SESSION["ScannersList"] as $item)
echo "<option value='".$item[0]."'>".$item[1]."</option>";
?>
</select>
</div>
<div class="mb-3">
<label for="outputImageResolutionFormSelect" class="form-label">Resolution of the scanned image:</label>
<select class="form-select" id="outputImageResolutionFormSelect" aria-label="Output image resolution select">
<?php
foreach($appConfig['outputImageResolution'] as $item)
{
if($item[2] === true) echo "<option value='".$item[0]."' selected>".$item[1]."</option>";
else echo "<option value='".$item[0]."'>".$item[1]."</option>";
}
?>
</select>
</div>
<div class="mb-3">
<label for="outputImageColorDepthFormSelect" class="form-label">Color depth of the scanned image:</label>
<select class="form-select" id="outputImageColorDepthFormSelect" aria-label="Output image color depth select">
<?php
foreach($appConfig['outputImageColorDepth'] as $item)
{
if($item[2] === true) echo "<option value='".$item[0]."' selected>".$item[1]."</option>";
else echo "<option value='".$item[0]."'>".$item[1]."</option>";
}
?>
</select>
</div>
<div class="mb-3">
<label for="outputFileFormatFormSelect" class="form-label">Output file format:</label>
<select class="form-select" id="outputFileFormatFormSelect" aria-label="Output file format select">
<?php
foreach($appConfig['outputImageFormats'] as $item)
{
if($item[2] === true) echo "<option value='".$item[0]."' selected>".$item[1]."</option>";
else echo "<option value='".$item[0]."'>".$item[1]."</option>";
}
?>
</select>
</div>
<div class="mb-3">
<label for="inputPageSizeFormSelect" class="form-label">Page size:</label>
<!-- Disabled as this option was removed in Debian 12 -->
<select class="form-select" id="inputPageSizeFormSelect" aria-label="Input page size select" disabled>
<option value="a4" selected>A4</option>
</select>
</div>
<div class="d-grid gap-2">
<button onclick='scanImage();' class='btn btn-primary' type='button'>Scan</button>
<a href="api/rediscover.php" class="btn btn-primary mt-2" role="button">Rediscover device</a>
<a id="scannedImageDownloadButton" class="btn btn-primary mt-2" style="display: none;" role="button">Download image</a>
</div>
</div>
<div class="col">
<p class="fw-medium">Scanned image preview</p>
<img id="scanPreview" src="assets/placeholderImage.png" class="img-fluid" alt="Scanned image preview">
</div>
</div>
</div>
<div id="scanningAnimationModal" class="modal" tabindex="-1">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-body">
<p>Scanning in progress...</p>
<div class="progress" role="progressbar">
<div class="progress-bar progress-bar-striped progress-bar-animated" style="width: 100%"></div>
</div>
</div>
</div>
</div>
</div>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js" integrity="sha384-YvpcrYf0tY3lHB60NNkmXc5s9fDVZLESaAA55NDzOxhy9GkcIdslK1eN7N6jIeHz" crossorigin="anonymous"></script>
</body>
</html>

79
js/appControl.js Normal file
View File

@@ -0,0 +1,79 @@
function discoverScanners(attemptID)
{
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function()
{
if (this.readyState == 4 && this.status == 200)
{
if(this.responseText == "OK")
{
location.href = "interface.php";
return true;
}
else
{
console.log("[Scanner discovery(attempt " + attemptID + ")] Failed with message: " + this.responseText);
setTimeout(discoverScanners, 2000, ++attemptID);
}
}
};
xhttp.open("GET", "api/discoverScanners.php", true);
xhttp.send();
if(attemptID > 3)
{
var progressBarElement = document.getElementById("scannerSearchProgress");
progressBarElement.innerHTML = '<div class="progress-bar progress-bar-striped progress-bar-animated bg-warning" style="width: 100%; color: black;">Attempt ' + attemptID + '</div>';
}
}
function scannersDiscoveryController()
{
var progressBarElement = document.getElementById("scannerSearchProgress");
if(progressBarElement != null) progressBarElement.innerHTML = '<div class="progress-bar progress-bar-striped progress-bar-animated" style="width: 100%"></div>';
else return;
discoverScanners(1);
}
function scanImage()
{
const scanningAnimationModal = new bootstrap.Modal(document.getElementById('scanningAnimationModal'));
var deviceID = document.getElementById("deviceIDFormSelect").value;
var outputImageResolution = document.getElementById("outputImageResolutionFormSelect").value;
var outputImageColorDepth = document.getElementById("outputImageColorDepthFormSelect").value;
var outputFileFormat = document.getElementById("outputFileFormatFormSelect").value;
var inputPageSize = document.getElementById("inputPageSizeFormSelect").value;
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function()
{
// TODO / DEBUG - Enable this
if (this.readyState == 4 && this.status == 200)
{
var scannedFileName = this.responseText;
var scannedImagePreview = document.getElementById("scanPreview");
scannedImagePreview.src = "api/imageDownload.php?filename=" + scannedFileName;
scannedImagePreview.alt = scannedFileName;
var scannedImageDownloadButton = document.getElementById("scannedImageDownloadButton");
scannedImageDownloadButton.href = "api/imageDownload.php?filename=" + scannedFileName;
scannedImageDownloadButton.style = "display: block;";
scanningAnimationModal.hide();
}
};
xhttp.open("GET", "api/scan.php?outputImageResolution=" + outputImageResolution + "&outputImageColorDepth=" + outputImageColorDepth + "&outputFileFormat=" + outputFileFormat + "&inputPageSize=" + inputPageSize + "&deviceID=" + deviceID, true);
xhttp.send();
scanningAnimationModal.show();
}
document.addEventListener("DOMContentLoaded", (event) => { scannersDiscoveryController(); });