From patchwork Mon Dec 27 13:21:36 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Leo-Andres Hofmann X-Patchwork-Id: 4941 Return-Path: Received: from mail01.ipfire.org (mail01.haj.ipfire.org [172.28.1.202]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-384) server-digest SHA384 client-signature ECDSA (P-384) client-digest SHA384) (Client CN "mail01.haj.ipfire.org", Issuer "R3" (verified OK)) by web04.haj.ipfire.org (Postfix) with ESMTPS id 4JMyxb4SzQz3wg9 for ; Mon, 27 Dec 2021 13:21:55 +0000 (UTC) Received: from mail02.haj.ipfire.org (mail02.haj.ipfire.org [172.28.1.201]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-384) server-digest SHA384 client-signature ECDSA (P-384) client-digest SHA384) (Client CN "mail02.haj.ipfire.org", Issuer "R3" (verified OK)) by mail01.ipfire.org (Postfix) with ESMTPS id 4JMyxY3qhxz17d; Mon, 27 Dec 2021 13:21:53 +0000 (UTC) Received: from mail02.haj.ipfire.org (localhost [127.0.0.1]) by mail02.haj.ipfire.org (Postfix) with ESMTP id 4JMyxY3JSFz2yWd; Mon, 27 Dec 2021 13:21:53 +0000 (UTC) Received: from mail01.ipfire.org (mail01.haj.ipfire.org [172.28.1.202]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-384) server-digest SHA384 client-signature ECDSA (P-384) client-digest SHA384) (Client CN "mail01.haj.ipfire.org", Issuer "R3" (verified OK)) by mail02.haj.ipfire.org (Postfix) with ESMTPS id 4JMyxX59THz2xPQ for ; Mon, 27 Dec 2021 13:21:52 +0000 (UTC) Received: from arche.uberspace.de (arche.uberspace.de [185.26.156.147]) (using TLSv1.2 with cipher ECDHE-ECDSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mail01.ipfire.org (Postfix) with ESMTPS id 4JMyxR2CKqzm for ; Mon, 27 Dec 2021 13:21:47 +0000 (UTC) Received: (qmail 17983 invoked by uid 990); 27 Dec 2021 13:21:46 -0000 From: Leo-Andres Hofmann To: development@lists.ipfire.org Subject: [PATCH 1/2] pakfire: Implement feedback from mailing list discussion Date: Mon, 27 Dec 2021 14:21:36 +0100 Message-Id: <20211227132137.1355-1-hofmann@leo-andres.de> X-Mailer: git-send-email 2.27.0.windows.1 In-Reply-To: <20211202153955.1126-1-hofmann@leo-andres.de> References: <20211202153955.1126-1-hofmann@leo-andres.de> MIME-Version: 1.0 X-Rspamd-Bar: - X-Rspamd-Report: MID_CONTAINS_FROM(1) MIME_HTML_ONLY(0.2) BAYES_HAM(-3) X-Rspamd-Score: -1.8 Received: from unknown (HELO unkown) (::1) by arche.uberspace.de (Haraka/2.8.28) with ESMTPSA; Mon, 27 Dec 2021 14:21:45 +0100 ARC-Seal: i=1; s=202003rsa; d=lists.ipfire.org; t=1640611307; a=rsa-sha256; cv=none; b=IEfr+VjSZ/mIdKNy7pSYrlhqDjSzzMTwWqc4TvSJpLrqFnv3k7xFjXzTbIarJ/GBt5uku7 UnL2W0n7I/8N4X7FaGrvNbKCNWQdXlUV5tJuYFXqFSV830X9lOPJG8NihiVN9dAvKKpWtg TUGogKbnA0KxocqqVb8C0Vi3Vmq50CVvnni6F4HDdEr5/63uqIBEGBlsItPD4nYL7byH8l +HSxjKm4DYEJMyvIt1uVdL9y6q+ARqbHmf4Pk9dfKTXWkDUefpnvve78+71t9fscC8ukfW FQA6lc8lysuotqEimYSxcxgNNTnelSKK9G/NubRkRmMj1U4ws0Fn5Re5zP+gww== ARC-Authentication-Results: i=1; mail01.ipfire.org; dkim=none; dmarc=pass (policy=quarantine) header.from=leo-andres.de; spf=pass (mail01.ipfire.org: domain of hofmann@leo-andres.de designates 185.26.156.147 as permitted sender) smtp.mailfrom=hofmann@leo-andres.de ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=lists.ipfire.org; s=202003rsa; t=1640611307; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=Okhcb2bPBE1ukxZadkKzZohTX+0shkxcAzyVAt8KYzM=; b=mItMmqDEbd/0wxfcpVKVHjKUKqeg257BZA9lwzP+Yh7YVgfS5uk+Er3/AdLDCTrbzFB7nV s1U+IRDYBCQBbNBCJKIAaEq3wFBkgssEpIMDeu85Zwq2h5Pdl6JpmL74ZZfpYJKG7r03/b 8kHOq3iAjx7o2ztL3K6/M6O3+la0h4zaYpR4opaX9vaoo1c0/KnyvhaTR98S6ZeYgaD/aS mUYv9BFaYBvSSLN5iORD4bnZVEGok1oqN2sBgafgKrvIDhCSEkW44swWFnOxcTZRe0DH/e gIr4A94IFSyBWe7VgxQR8L/1d5G++zNpCBtqR3yboiGt2BbZLka68zZh9uKjzw== Authentication-Results: mail01.ipfire.org; dkim=none; dmarc=pass (policy=quarantine) header.from=leo-andres.de; spf=pass (mail01.ipfire.org: domain of hofmann@leo-andres.de designates 185.26.156.147 as permitted sender) smtp.mailfrom=hofmann@leo-andres.de X-Rspamd-Server: mail01.haj.ipfire.org X-Spamd-Result: default: False [-3.35 / 11.00]; BAYES_HAM(-3.00)[99.99%]; MID_CONTAINS_FROM(1.00)[]; SPF_REPUTATION_HAM(-0.91)[-0.90940212585203]; DMARC_POLICY_ALLOW(-0.50)[leo-andres.de,quarantine]; MX_INVALID(0.50)[]; NEURAL_HAM(-0.44)[-0.436]; MIME_HTML_ONLY(0.20)[]; R_SPF_ALLOW(-0.20)[+mx]; IP_REPUTATION_HAM(-0.01)[asn: 205766(0.00), country: DE(-0.01), ip: 185.26.156.147(0.00)]; FROM_EQ_ENVFROM(0.00)[]; ASN(0.00)[asn:205766, ipnet:185.26.156.0/24, country:DE]; MIME_TRACE(0.00)[0:~]; R_DKIM_NA(0.00)[]; RCVD_VIA_SMTP_AUTH(0.00)[]; RCPT_COUNT_ONE(0.00)[1]; FROM_HAS_DN(0.00)[]; ARC_NA(0.00)[]; RCVD_COUNT_TWO(0.00)[2]; TO_MATCH_ENVRCPT_ALL(0.00)[]; ARC_SIGNED(0.00)[lists.ipfire.org:s=202003rsa:i=1]; TO_DN_NONE(0.00)[]; RCVD_TLS_ALL(0.00)[] X-Rspamd-Queue-Id: 4JMyxR2CKqzm X-BeenThere: development@lists.ipfire.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: IPFire development talk List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: development-bounces@lists.ipfire.org Sender: "Development" - Improve lockfile test: Return immediately if lockfile is present, to prevent unnecessary and expensive "pidof" calls - Add better explanation to the log file reading command and JS - Change user interface: If no errors occurred, the page returns to the main screen (after a short delay). If an error occurred, the log output remains and a message is shown. Signed-off-by: Leo-Andres Hofmann Acked-by: Peter Müller --- html/cgi-bin/pakfire.cgi | 42 ++++++++++++---- html/html/include/pakfire.js | 96 ++++++++++++++++++++++++++++++++++-- langs/de/cgi-bin/de.pl | 3 +- langs/en/cgi-bin/en.pl | 3 +- 4 files changed, 127 insertions(+), 17 deletions(-) diff --git a/html/cgi-bin/pakfire.cgi b/html/cgi-bin/pakfire.cgi index e14658ffb..8516b07b1 100644 --- a/html/cgi-bin/pakfire.cgi +++ b/html/cgi-bin/pakfire.cgi @@ -20,6 +20,7 @@ ############################################################################### use strict; +use List::Util qw(any); # enable only the following on debugging purpose #use warnings; @@ -54,13 +55,20 @@ if($cgiparams{'ACTION'} eq 'json-getstatus') { # Send HTTP headers _start_json_output(); - # Collect Pakfire status and log messages + # Read /var/log/messages backwards until a "Pakfire started" header is found, + # to capture all messages of the last (i.e. current) Pakfire run + my @messages = `tac /var/log/messages | sed -n '/pakfire:/{p;/Pakfire.*started/q}'`; + + # Test if the log contains an error message (fastest implementation, stops at first match) + my $failure = any{ index($_, 'ERROR') != -1 } @messages; + + # Collect Pakfire status my %status = ( 'running' => &_is_pakfire_busy() || "0", 'running_since' => &General::age("$Pakfire::lockfile") || "0s", - 'reboot' => (-e "/var/run/need_reboot") || "0" + 'reboot' => (-e "/var/run/need_reboot") || "0", + 'failure' => $failure || "0" ); - my @messages = `tac /var/log/messages | sed -n '/pakfire:/{p;/Pakfire.*started/q}'`; # Start JSON file print "{\n"; @@ -128,14 +136,18 @@ my $extraHead = <$Lang::tr{'pakfire return'}', 'link_reboot': '$Lang::tr{'needreboot'}' }); - - // AJAX auto refresh interval - pakfire.refreshInterval = 1000; + + // AJAX auto refresh interval (in ms, default: 1000) + //pakfire.refreshInterval = 1000; + + // Enable returning to main screen (delay in ms) + pakfire.setupPageReload(true, 3000); END ; @@ -276,6 +288,7 @@ if(&_is_pakfire_busy()) {

 
 
@@ -401,13 +414,22 @@ END
 
 # Check if pakfire is already running (extend test here if necessary)
 sub _is_pakfire_busy {
-	# Get PID of a running pakfire instance
+	# Return immediately if lockfile is present
+	if(-e "$Pakfire::lockfile") {
+		return 1;
+	}
+
+	# Check if a PID of a running pakfire instance is found
 	# (The system backpipe command is safe, because no user input is computed.)
 	my $pakfire_pid = `pidof -s /usr/local/bin/pakfire`;
 	chomp($pakfire_pid);
 
-	# Test presence of PID or lockfile
-	return (($pakfire_pid) || (-e "$Pakfire::lockfile"));
+	if($pakfire_pid) {
+		return 1;
+	}
+
+	# Pakfire isn't running
+	return 0;
 }
 
 # Send HTTP headers
diff --git a/html/html/include/pakfire.js b/html/html/include/pakfire.js
index 0950870e0..44a40c75f 100644
--- a/html/html/include/pakfire.js
+++ b/html/html/include/pakfire.js
@@ -32,12 +32,13 @@ class PakfireJS {
 		this._states = Object.create(null);
 		this._states.running = false;
 		this._states.reboot = false;
+		this._states.failure = false;
 
 		// Status refresh helper
 		this._autoRefresh = {
-			delay: 1000, //Delay between requests (default: 1s)
+			delay: 1000, //Delay between requests (minimum: 500, default: 1s)
 			jsonAction: 'getstatus', //CGI POST action parameter
-			timeout: 5000, //XHR timeout (5s)
+			timeout: 5000, //XHR timeout (0 to disable, default: 5s)
 
 			delayTimer: null, //setTimeout reference
 			jqXHR: undefined, //jQuery.ajax promise reference
@@ -51,10 +52,32 @@ class PakfireJS {
 				return (this.runningDelay || this.runningXHR);
 			}
 		};
+
+		// Return to main screen helper
+		this._pageReload = {
+			delay: 1000, //Delay before page reload (default: 1s)
+			enabled: false, //Reload disabled by default
+
+			delayTimer: null, //setTimeout reference
+			get isTriggered() { //Reload timer started
+				return (this.delayTimer !== null);
+			}
+		};
 	}
 
 	//### Public properties ###
 
+	// Note on using the status flags
+	// running: Pakfire is performing a task.
+	//    Writing "true" activates the periodic AJAX/JSON status polling, writing "false" stops polling.
+	//    When the task has been completed, status polling stops and this returns to "false".
+	//    The page can then be reloaded to go back to the main screen. Writing "false" does not trigger a reload.
+	//    "refreshInterval" and "setupPageReload" can be used to adjust the respective behaviour.
+	// reboot: An update requires a reboot.
+	//    If set to "true", a link to the reboot menu is shown after the task is completed.
+	// failure: An error has occured.
+	//    To display the error log, the page does not return to the main screen.
+
 	// Pakfire is running (true/false)
 	set running(state) {
 		if(this._states.running !== state) {
@@ -77,6 +100,17 @@ class PakfireJS {
 		return this._states.reboot;
 	}
 
+	// Error encountered (true/false)
+	set failure(state) {
+		if(this._states.failure !== state) {
+			this._states.failure = state;
+			this._states_onChange('failure');
+		}
+	}
+	get failure() {
+		return this._states.failure;
+	}
+
 	// Status refresh interval in ms
 	set refreshInterval(delay) {
 		if(delay < 500) {
@@ -88,6 +122,16 @@ class PakfireJS {
 		return this._autoRefresh.delay;
 	}
 
+	// Configure page reload after successful task (returns to main screen)
+	// delay: In ms
+	setupPageReload(enabled, delay) {
+		if(delay < 0) {
+			delay = 0;
+		}
+		this._pageReload.delay = delay;
+		this._pageReload.enabled = enabled;
+	}
+
 	// Document loaded (call once from jQuery.ready)
 	documentReady() {
 		// Status refresh late start
@@ -96,6 +140,12 @@ class PakfireJS {
 		}
 	}
 
+	// Reload entire CGI page (clears POST/GET data from history)
+	documentReload() {
+		let url = window.location.origin + window.location.pathname;
+		window.location.replace(url);
+	}
+
 	//### Private properties ###
 
 	// Pakfire status change handler
@@ -106,9 +156,13 @@ class PakfireJS {
 			$('#pflog-status').text(this.i18n.get('working'));
 			$('#pflog-action').empty();
 		} else {
-			$('#pflog-status').text(this.i18n.get('finished'));
+			if(this.failure) {
+				$('#pflog-status').text(this.i18n.get('finished error'));
+			} else {
+				$('#pflog-status').text(this.i18n.get('finished'));
+			}
 			if(this.reboot) { //Enable return or reboot links in UI
-				$('#pflog-action').html(this.i18n.get('link_reboot'));
+				$('#pflog-action').html(this.i18n.get('link_return') + " • " + this.i18n.get('link_reboot'));
 			} else {
 				$('#pflog-action').html(this.i18n.get('link_return'));
 			}
@@ -122,6 +176,13 @@ class PakfireJS {
 				this._autoRefresh_clearSchedule();
 			}
 		}
+
+		// Always stay in the log viewer if Pakfire failed
+		if(property === 'failure') {
+			if(this.failure) {
+				this._pageReload_cancel();
+			}
+		}
 	}
 
 	//--- Status refresh scheduling functions ---
@@ -164,6 +225,25 @@ class PakfireJS {
 		}
 	}
 
+	// Start delayed page reload to return to main screen
+	_pageReload_trigger() {
+		if((! this._pageReload.enabled) || this._pageReload.isTriggered) {
+			return; // Disabled or already started
+		}
+		this._pageReload.delayTimer = window.setTimeout(function() {
+			this._pageReload.delayTimer = null;
+			this.documentReload();
+		}.bind(this), this._pageReload.delay);
+	}
+
+	// Stop scheduled reload
+	_pageReload_cancel() {
+		if(this._pageReload.isTriggered) {
+			window.clearTimeout(this._pageReload.delayTimer);
+			this._pageReload.delayTimer = null;
+		}
+	}
+
 	//--- JSON request & data handling ---
 
 	// Load JSON data from Pakfire CGI, using a POST request
@@ -192,10 +272,11 @@ class PakfireJS {
 			// Update status flags
 			this.running = (data['running'] != '0');
 			this.reboot = (data['reboot'] != '0');
+			this.failure = (data['failure'] != '0');
 
 			// Update timer display
 			if(this.running && data['running_since']) {
-				$('#pflog-time').text(this.i18n.get('since') + data['running_since']);
+				$('#pflog-time').text(this.i18n.get('since') + " " + data['running_since']);
 			} else {
 				$('#pflog-time').empty();
 			}
@@ -206,6 +287,11 @@ class PakfireJS {
 				messages += `${line}\n`;
 			});
 			$('#pflog-messages').text(messages);
+
+			// Pakfire finished without errors, return to main screen
+			if((! this.running) && (! this.failure)) {
+				this._pageReload_trigger();
+			}
 		}
 	}
 }
diff --git a/langs/de/cgi-bin/de.pl b/langs/de/cgi-bin/de.pl
index 490879c90..dd946081d 100644
--- a/langs/de/cgi-bin/de.pl
+++ b/langs/de/cgi-bin/de.pl
@@ -1974,7 +1974,8 @@
 'pakfire configuration' => 'Pakfire Konfiguration',
 'pakfire core update auto' => 'Core- und Addon-Updates automatisch installieren:',
 'pakfire core update level' => 'Core-Update-Level',
-'pakfire finished' => 'Pakfire ist fertig!. Bitte überprüfen Sie die Log Ausgabe.',
+'pakfire finished' => 'Pakfire ist fertig! Kehre zurück...',
+'pakfire finished error' => 'Pakfire ist fertig! Fehler sind aufgetreten, bitte überprüfen Sie die Log-Ausgabe, bevor Sie fortfahren.',
 'pakfire health check' => 'Mirrors auf Erreichbarkeit prüfen (Ping):',
 'pakfire install description' => 'Wählen Sie ein oder mehrere Pakete zur Installation aus und drücken Sie auf das plus-Symbol.',
 'pakfire install package' => 'Sie möchten folgende Pakete installieren: ',
diff --git a/langs/en/cgi-bin/en.pl b/langs/en/cgi-bin/en.pl
index 4442ea772..fc5a57cb0 100644
--- a/langs/en/cgi-bin/en.pl
+++ b/langs/en/cgi-bin/en.pl
@@ -2009,7 +2009,8 @@
 'pakfire configuration' => 'Pakfire Configuration',
 'pakfire core update auto' => 'Install core and addon updates automatically:',
 'pakfire core update level' => 'Core-Update-Level',
-'pakfire finished' => 'Pakfire is finished! Please check the log output.',
+'pakfire finished' => 'Pakfire has finished! Returning...',
+'pakfire finished error' => 'Pakfire has finished! Errors occurred, please check the log output before proceeding.',
 'pakfire health check' => 'Check if mirror is reachable (ping):',
 'pakfire install description' => 'Please choose one or more items from the list below and click the plus to install.',
 'pakfire install package' => 'You want to install the following packages: ',

From patchwork Mon Dec 27 13:21:37 2021
Content-Type: text/plain; charset="utf-8"
MIME-Version: 1.0
Content-Transfer-Encoding: 8bit
X-Patchwork-Submitter: Leo-Andres Hofmann 
X-Patchwork-Id: 4942
Return-Path: 
Received: from mail01.ipfire.org (mail01.haj.ipfire.org [172.28.1.202])
	(using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)
	 key-exchange X25519 server-signature ECDSA (P-384)
	 client-signature ECDSA (P-384))
	(Client CN "mail01.haj.ipfire.org", Issuer "R3" (verified OK))
	by web04.haj.ipfire.org (Postfix) with ESMTPS id 4JMyxc0Pywz3wt5
	for ; Mon, 27 Dec 2021 13:21:56 +0000 (UTC)
Received: from mail02.haj.ipfire.org (mail02.haj.ipfire.org [172.28.1.201])
	(using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)
	 key-exchange X25519 server-signature ECDSA (P-384)
	 client-signature ECDSA (P-384))
	(Client CN "mail02.haj.ipfire.org", Issuer "R3" (verified OK))
	by mail01.ipfire.org (Postfix) with ESMTPS id 4JMyxY4pw4z28g;
	Mon, 27 Dec 2021 13:21:53 +0000 (UTC)
Received: from mail02.haj.ipfire.org (localhost [127.0.0.1])
	by mail02.haj.ipfire.org (Postfix) with ESMTP id 4JMyxY45rWz30HK;
	Mon, 27 Dec 2021 13:21:53 +0000 (UTC)
Received: from mail01.ipfire.org (mail01.haj.ipfire.org [172.28.1.202])
 (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)
 key-exchange X25519 server-signature ECDSA (P-384)
 client-signature ECDSA (P-384))
 (Client CN "mail01.haj.ipfire.org", Issuer "R3" (verified OK))
 by mail02.haj.ipfire.org (Postfix) with ESMTPS id 4JMyxX5Z75z2y51
 for ; Mon, 27 Dec 2021 13:21:52 +0000 (UTC)
Received: from arche.uberspace.de (arche.uberspace.de [185.26.156.147])
 (using TLSv1.2 with cipher ECDHE-ECDSA-AES256-GCM-SHA384 (256/256 bits))
 (Client did not present a certificate)
 by mail01.ipfire.org (Postfix) with ESMTPS id 4JMyxR2R5Pzpg
 for ; Mon, 27 Dec 2021 13:21:47 +0000 (UTC)
Received: (qmail 17988 invoked by uid 990); 27 Dec 2021 13:21:46 -0000
From: Leo-Andres Hofmann 
To: development@lists.ipfire.org
Subject: [PATCH 2/2] pakfire.cgi: Improve HTML output and layout
Date: Mon, 27 Dec 2021 14:21:37 +0100
Message-Id: <20211227132137.1355-2-hofmann@leo-andres.de>
X-Mailer: git-send-email 2.27.0.windows.1
In-Reply-To: <20211227132137.1355-1-hofmann@leo-andres.de>
References: <20211202153955.1126-1-hofmann@leo-andres.de>
 <20211227132137.1355-1-hofmann@leo-andres.de>
MIME-Version: 1.0
X-Rspamd-Bar: -
X-Rspamd-Report: R_MISSING_CHARSET(0.5) MID_CONTAINS_FROM(1)
 MIME_HTML_ONLY(0.2) BAYES_HAM(-3)
X-Rspamd-Score: -1.3
Received: from unknown (HELO unkown) (::1)
 by arche.uberspace.de (Haraka/2.8.28) with ESMTPSA;
 Mon, 27 Dec 2021 14:21:46 +0100
ARC-Seal: i=1; s=202003rsa; d=lists.ipfire.org; t=1640611307; a=rsa-sha256;
 cv=none;
 b=P70kTMAlxWtxXXcY0PMEgeRTRB2X6lQRBgWK8D/pvjFxtuO2cIs45p/X72w81GQX+nBWmi
 xj24WKU+pPGyqLYyRUwn2H3KxiouL8xTMSw7gInwJLgTcCcucwAS+ZTMGHjCEHohst4yLX
 5n9zsPUQY2V00GVborZN6fP4Xf9nzatnVp79mPkFvjKsKxofwcnTIbJy8k6x3ki9iRahN1
 OPCBYvp2SsPHmQARhSxI1Hm0ka1oMaQWvJQ2LvVAFsOwLYa0v8+O1LllSz9cR2lHsEAtIN
 mskCqBpoiL5tU3sortoIqGhkLYrUIpovncIynHe73QO2Co/AZ+5eKuyW2CvN/A==
ARC-Authentication-Results: i=1; mail01.ipfire.org; dkim=none;
 dmarc=pass (policy=quarantine) header.from=leo-andres.de;
 spf=pass (mail01.ipfire.org: domain of hofmann@leo-andres.de designates
 185.26.156.147 as permitted sender) smtp.mailfrom=hofmann@leo-andres.de
ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed;
 d=lists.ipfire.org;
 s=202003rsa; t=1640611307;
 h=from:from:reply-to:subject:subject:date:date:message-id:message-id:
 to:to:cc:mime-version:mime-version:
 content-transfer-encoding:content-transfer-encoding:
 in-reply-to:in-reply-to:references:references;
 bh=P2z1vnSVU8NxHtxcMpFjY7s9So5iqTYOc4dXXBhPLwU=;
 b=jL2II8QmvvKkYzli2IC3tjiKcb4upcsZy5YOARTlTdZRtGXZwabef4HsuB+LNsIKbvtEHs
 0/SJ2lt/5CpTC9GioVjVB0Sp1Eiv7ppylwvCMlEga8mCEI74WAS5I2obAAYB7W5ANbH9H7
 MVCiMElXYn15nT7Q1gu3alIiHqWmKPLT6i6McHDvoU32oOYg6HXnrbNQ7AZeL9ksYg1JbB
 piRe4k+XVMyxoKIHqrTRCpLPhL6SwsELp6socIF+hop0qJUTG6tmkTvG7r3SziO4nNz2j+
 zVWRLdviHYyi6F93tAksLyYbO3sxqkciQ3cDRYuoxrSuEH1kNKf+GaI8bKEEPw==
Authentication-Results: mail01.ipfire.org; dkim=none;
 dmarc=pass (policy=quarantine) header.from=leo-andres.de;
 spf=pass (mail01.ipfire.org: domain of hofmann@leo-andres.de designates
 185.26.156.147 as permitted sender) smtp.mailfrom=hofmann@leo-andres.de
X-Rspamd-Server: mail01.haj.ipfire.org
X-Spamd-Result: default: False [-1.69 / 11.00]; BAYES_HAM(-3.00)[99.99%];
 MID_CONTAINS_FROM(1.00)[];
 SPF_REPUTATION_HAM(-0.91)[-0.90940212585203];
 NEURAL_SPAM(0.72)[0.724]; R_MISSING_CHARSET(0.50)[];
 MX_INVALID(0.50)[];
 DMARC_POLICY_ALLOW(-0.50)[leo-andres.de,quarantine];
 MIME_HTML_ONLY(0.20)[]; R_SPF_ALLOW(-0.20)[+mx];
 IP_REPUTATION_HAM(-0.01)[asn: 205766(0.00), country: DE(-0.01), ip:
 185.26.156.147(0.00)]; MIME_TRACE(0.00)[0:~];
 FROM_EQ_ENVFROM(0.00)[];
 ASN(0.00)[asn:205766, ipnet:185.26.156.0/24, country:DE];
 R_DKIM_NA(0.00)[]; RCVD_VIA_SMTP_AUTH(0.00)[];
 RCPT_COUNT_ONE(0.00)[1]; FROM_HAS_DN(0.00)[]; ARC_NA(0.00)[];
 RCVD_COUNT_TWO(0.00)[2]; TO_MATCH_ENVRCPT_ALL(0.00)[];
 ARC_SIGNED(0.00)[lists.ipfire.org:s=202003rsa:i=1];
 TO_DN_NONE(0.00)[]; RCVD_TLS_ALL(0.00)[]
X-Rspamd-Queue-Id: 4JMyxR2R5Pzpg
X-BeenThere: development@lists.ipfire.org
X-Mailman-Version: 2.1.29
Precedence: list
List-Id: IPFire development talk 
List-Unsubscribe: ,
 
List-Archive: 
List-Post: 
List-Help: 
List-Subscribe: ,
 
Errors-To: development-bounces@lists.ipfire.org
Sender: "Development" 

Add missing closing tags, indentation and CSS styling.
Add link to reboot notice, left-align info list and resize packages
lists for better readability.

Signed-off-by: Leo-Andres Hofmann 
Acked-by: Peter Müller 
---

Hi all,

this patch series implements everything that came up in the discussion so far and fixes a few HTML issues I found along the way.
Because more changes are probably needed, I have not yet created a new patchset. Instead, this patch builds on the first proposal. 

To test it, the following patches must therefore also be applied:
https://patchwork.ipfire.org/patch/4842
https://patchwork.ipfire.org/project/ipfire/list/?series=2452

I hope this doesn't cause confusion again, if it does, I can of course build a new patchset :)

Happy holidays!
Leo

 html/cgi-bin/pakfire.cgi | 137 ++++++++++++++++++++++++---------------
 1 file changed, 84 insertions(+), 53 deletions(-)

diff --git a/html/cgi-bin/pakfire.cgi b/html/cgi-bin/pakfire.cgi
index 8516b07b1..51f586aa2 100644
--- a/html/cgi-bin/pakfire.cgi
+++ b/html/cgi-bin/pakfire.cgi
@@ -100,6 +100,32 @@ if($cgiparams{'ACTION'} eq 'json-getstatus') {
 ###--- HTML HEAD ---###
 my $extraHead = <
+	/* Main screen */
+	table#pfmain {
+		width: 100%;
+		border-style: hidden;
+		table-layout: fixed;
+	}
+
+	#pfmain td {
+		padding: 5px 20px 0;
+		text-align: center;
+	}
+	#pfmain tr:not(:last-child) > td {
+		padding-bottom: 1.5em;
+	}
+	#pfmain tr > td.heading {
+		padding: 0;
+		font-weight: bold;
+		background-color: $color{'color20'};
+	}
+
+	.pflist {
+		width: 100%;
+		text-align: left;
+		margin-bottom: 0.8em;
+	}
+
 	/* Pakfire log viewer */
 	section#pflog-header {
 		width: 100%;
@@ -173,20 +199,23 @@ END
 			print "$_\n";
 		}
 		print <
-		$Lang::tr{'pakfire accept all'}
-		 
+		
+		$Lang::tr{'pakfire accept all'}
+		 
 		
+
+ + END &Header::closebox(); @@ -210,20 +239,23 @@ END print "$_\n"; } print < - $Lang::tr{'pakfire uninstall all'} -   + + $Lang::tr{'pakfire uninstall all'} +  
+
+ + END &Header::closebox(); @@ -311,70 +343,69 @@ my $packages_update_age = &General::age("/opt/pakfire/db/lists/packages_list.db" &Header::openbox("100%", "center", "Pakfire"); print < + END if ( -e "/var/run/need_reboot") { - print ""; - print "" + print "\t\t\n"; } print < - - + + + + + + + - + +
$Lang::tr{'needreboot'}!
 
$Lang::tr{'needreboot'}!
$Lang::tr{'pakfire system state'}: - - $Lang::tr{'available updates'}:
$Lang::tr{'pakfire core update level'}: $core_release
- $Lang::tr{'pakfire last update'} $core_update_age $Lang::tr{'pakfire ago'}
- $Lang::tr{'pakfire last serverlist update'} $server_update_age $Lang::tr{'pakfire ago'}
- $Lang::tr{'pakfire last core list update'} $corelist_update_age $Lang::tr{'pakfire ago'}
+
$Lang::tr{'pakfire system state'}:$Lang::tr{'available updates'}:
$Lang::tr{'pakfire core update level'}: $core_release +
+
+ $Lang::tr{'pakfire last update'} $core_update_age $Lang::tr{'pakfire ago'}
+ $Lang::tr{'pakfire last serverlist update'} $server_update_age $Lang::tr{'pakfire ago'}
+ $Lang::tr{'pakfire last core list update'} $corelist_update_age $Lang::tr{'pakfire ago'}
$Lang::tr{'pakfire last package update'} $packages_update_age $Lang::tr{'pakfire ago'} -
-
-
-
-
-
+
- + +
+
+
+
+
$Lang::tr{'pakfire available addons'}$Lang::tr{'pakfire installed addons'}
  -
$Lang::tr{'pakfire available addons'} - $Lang::tr{'pakfire installed addons'} -
-

$Lang::tr{'pakfire install description'}

-
-

$Lang::tr{'pakfire install description'}

+ + - - - -
-

$Lang::tr{'pakfire uninstall description'}

-
- + +
+

$Lang::tr{'pakfire uninstall description'}

+
+ - -
+ &Pakfire::dblist("installed", "forweb"); + print < + + + +
END