aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--controllers/archive.php76
-rw-r--r--views/admin/index.php18
-rw-r--r--views/archive/create/index.php47
-rw-r--r--views/archive/create/status.php5
4 files changed, 142 insertions, 4 deletions
diff --git a/controllers/archive.php b/controllers/archive.php
index 367acc7..4e4ac77 100644
--- a/controllers/archive.php
+++ b/controllers/archive.php
@@ -3,24 +3,76 @@ namespace Controller;
use Database;
use DOMDocument;
use Exception;
+use TypeError;
+use ValueError;
function on_post() {
+ if (!array_key_exists('async', $_POST) || $_POST['async'] !== 'true') {
+ return;
+ }
+
+ session_start();
+
global $TOKEN;
$WEBSITE_CATEGORY = 'url';
$DOWNLOADS_FOLDER = getenv('ARCHIVES_DIR');
$website_url = $_POST[$WEBSITE_CATEGORY];
$uid = 1;
+ $authorized = false;
if ($TOKEN !== "") {
try {
- $uid = Database\Cookie::fromDB($TOKEN)->UID;
+ $user = Database\Cookie::fromDB($TOKEN);
+ $uid = $user->UID;
+ $authorized = $user->Role === 'Admin';
}
catch (Exception $e) {}
}
- $currentPage = new DownloadPage($website_url, $DOWNLOADS_FOLDER, $uid);
- header('Location: /archive/?url=' . $website_url);
- exit();
+ $manual_start = $authorized
+ && array_key_exists('manual', $_POST)
+ && $_POST['manual'] === 'true';
+ // The first request to archive a page becomes a "worker", which will archive
+ // the requested page and any other which might be requested in the meantime
+ $start_worker = !array_key_exists('archive_queue', $_SESSION)
+ || count($_SESSION['archive_queue']) === 0
+ || $manual_start;
+
+ if (!array_key_exists('archive_queue', $_SESSION)) {
+ $_SESSION['archive_queue'] = array();
+ $_SESSION['archive_current'] = 0;
+ }
+ else if ($start_worker) {
+ $_SESSION['archive_current'] = 0;
+ }
+
+ $current = $_SESSION['archive_current'] + count($_SESSION['archive_queue']);
+ if (!$manual_start) {
+ array_push(
+ $_SESSION['archive_queue'],
+ new DownloadInfo($website_url, $DOWNLOADS_FOLDER, $uid)
+ );
+ }
+
+ if ($start_worker) {
+ while (count($_SESSION['archive_queue']) > 0) {
+ $downloadInfo = $_SESSION['archive_queue'][0];
+ session_write_close();
+
+ try {
+ $downloadInfo->download();
+ }
+ catch(Exception $e) { }
+ catch(TypeError $e) { }
+ catch(ValueError $e) { }
+
+ session_start();
+ array_shift($_SESSION['archive_queue']);
+ $_SESSION['archive_current']++;
+ }
+ }
+ echo $current;
+ exit;
}
function on_delete() {
@@ -57,6 +109,22 @@ function on_delete() {
exit();
}
+class DownloadInfo {
+ public $page_url;
+ private $folder_location;
+ private $requester_uid;
+
+ function __construct(string $page_url, string $folder_location, string $requester_uid) {
+ $this->page_url = $page_url;
+ $this->folder_location = $folder_location;
+ $this->requester_uid = $requester_uid;
+ }
+
+ function download() : DownloadPage {
+ return new DownloadPage($this->page_url, $this->folder_location, $this->requester_uid);
+ }
+}
+
class DownloadPage {
private $folder_location;
private $folder_name;
diff --git a/views/admin/index.php b/views/admin/index.php
index 750a246..e633d32 100644
--- a/views/admin/index.php
+++ b/views/admin/index.php
@@ -35,6 +35,24 @@
<input type="submit" value="Delete">
</form>
+ <h2>Archive queue</h2>
+
+ <button id="manual-start">Start worker manually</button>
+ <script type="text/javascript">
+ document.getElementById('manual-start').onclick = function() {
+ var request = new XMLHttpRequest();
+ request.onreadystatechange = function() {
+ if (request.readyState < 4) return;
+
+ console.log(request.responseText);
+ }
+ request.open("POST", "/archive/create", true);
+ request.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
+ request.withCredentials = true;
+ request.send('async=true&url=localhost&manual=true');
+ }
+ </script>
+
<?php else: ?>
<h2>Permission denied, you're not an admin!</h2>
diff --git a/views/archive/create/index.php b/views/archive/create/index.php
index 378d2de..b435e4d 100644
--- a/views/archive/create/index.php
+++ b/views/archive/create/index.php
@@ -1 +1,48 @@
<h2>Archiving <?= $url ?>...</h2>
+
+<p>Current position in queue: <span id="position">unavailable</span></p>
+
+<script type="text/javascript">
+// If our request is the one that starts the worker, it's output will be 0
+// and it won't update the variable soon (or ever)
+// But if it's not the worker, the variable will be updated (quickly)
+var queuePos = 0;
+
+function requestDownload(url) {
+ var request = new XMLHttpRequest();
+ request.onreadystatechange = function() {
+ if (request.readyState < 4) return;
+
+ console.log(request.responseText);
+ queuePos = request.responseText;
+ }
+ request.open("POST", "#", true);
+ request.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
+ request.withCredentials = true;
+ request.send('async=true&url=' +
+ url +
+ '<?php if (array_key_exists("manual", $_POST)) { echo "&manual=" . $_POST["manual"]; } ?>');
+}
+requestDownload('<?= $url ?>');
+
+const position = document.getElementById('position');
+function updatePosition(url) {
+ var request = new XMLHttpRequest();
+ request.onreadystatechange = function() {
+ if (request.readyState < 4) return;
+
+ if (queuePos < request.responseText) {
+ window.location.href = '/archive/?url=' + url;
+ return;
+ }
+
+ position.innerText = queuePos - request.responseText;
+ setTimeout(updatePosition, 1000, url);
+ }
+ request.open("POST", "/archive/create/status.php", true);
+ request.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
+ request.send('url=' + url);
+}
+
+updatePosition('<?= $url ?>');
+</script>
diff --git a/views/archive/create/status.php b/views/archive/create/status.php
new file mode 100644
index 0000000..d020c4a
--- /dev/null
+++ b/views/archive/create/status.php
@@ -0,0 +1,5 @@
+<?php
+
+session_start();
+
+echo $_SESSION['archive_current'];