diff --git a/.phpenv b/.phpenv index 8040b40c..5ff259de 100644 --- a/.phpenv +++ b/.phpenv @@ -9,6 +9,16 @@ include_once "$PROJECT_ROOT/php/utils/logging.php"; + // Read the -v|--verbose option increasing logging verbosity to debug. + $options = getopt("v", ["verbose", "fast"]); + if (isset($options["v"]) or isset($options["verbose"])) { + $LOGGING_VERBOSITY = LoggingVerbosity::Debug; + } + + if (isset($options["fast"])) { + $FAST_FETCH_MODE = true; + } + // set timeout for file_get_contents() ini_set('default_socket_timeout', 6); // in seconds, default is 60 diff --git a/Makefile b/Makefile index f123dafe..614a3660 100644 --- a/Makefile +++ b/Makefile @@ -1,5 +1,7 @@ -port = 8081 -output = output +PORT ?= 8081 +OUTPUT ?= output +FLAGS ?= +MAKE = make FLAGS=$(FLAGS) # First goal is the default with `make`. @@ -14,54 +16,54 @@ all: fetch html # Fetch room listing. fetch: - /bin/php php/fetch-servers.php - -# Fetch room listing with extra verbosity. -fetch-v: - /bin/php php/fetch-servers.php --verbose + /bin/php php/fetch-servers.php $(FLAGS) # Generate HTML from data. html: - /bin/php php/generate-html.php - -# Last item run in foreground to receive interrupts. + /bin/php php/generate-html.php $(FLAGS) # Serve a local copy which responds to file changes. +dev: FLAGS = --verbose dev: open - make server & - make watchdog + $(MAKE) server & + $(MAKE) watchdog + +# (Last item run in foreground to receive interrupts.) # Serve a local copy on LAN which responds to file changes. +lan-dev: FLAGS = --verbose lan-dev: open - ip addr | fgrep -e ' 192.' -e ' 10.' - make lan-server & - make watchdog + -which ip 1>/dev/null 2>/dev/null && ip addr | fgrep -e ' 192.' -e ' 10.' || true + $(MAKE) lan-server & + $(MAKE) watchdog # Serve a local copy. server: - /bin/php -S localhost:$(port) -t $(output) + /bin/php -S "localhost:$(PORT)" -t "$(OUTPUT)" # Serve a local copy on all interfaces. lan-server: - /bin/php -S 0.0.0.0:$(port) -t $(output) + /bin/php -S "0.0.0.0:$(PORT)" -t "$(OUTPUT)" # Open locally served page in browser. open: - xdg-open http://localhost:$(port) >/dev/null 2>/dev/null & disown + xdg-open "http://localhost:$(PORT)" >/dev/null 2>/dev/null & disown # Update HTML on file change. Doesn't check for new files. watchdog: - find . | entr -n -s "make html" + find . | grep -v ".git" | entr -n -s "$(MAKE) html" # Remove artefacts clean: - -rm -r cache - -rm -r output/*.html + -rm -r cache 2>/dev/null || true + -rm -r output/*.html 2>/dev/null || true # Build everything from scratch and test functionality. +test: FLAGS = --verbose test: clean all open server # Build everything from scratch and test functionality on LAN. +test-lan: FLAGS = --verbose test-lan: clean all open lan-server # -- Aliases -- diff --git a/output/styles2.css b/output/styles2.css index 7b95ab65..52d3e3d5 100644 --- a/output/styles2.css +++ b/output/styles2.css @@ -58,7 +58,6 @@ html.js .noscript, .hidden { } html:not(.js) .js-only { - /* Dead style */ display: none; } @@ -322,7 +321,7 @@ footer { max-width: 100%; text-align: center; - padding-top: var(--body-margin); + padding-bottom: var(--body-margin); padding-inline: var(--body-margin); } diff --git a/php/fetch-servers.php b/php/fetch-servers.php index 945c4b6f..7a946f45 100644 --- a/php/fetch-servers.php +++ b/php/fetch-servers.php @@ -10,8 +10,6 @@ // Not required include_once "$LANGUAGES_ROOT/language_flags.php"; - $FAST_FETCH_MODE = false; - /** * Fetch online Communities and write the resulting data to disk. * Communities are fetched as follows: @@ -24,18 +22,6 @@ * 6. De-dupe servers based on pubkey */ function main() { - global $LOGGING_VERBOSITY, $FAST_FETCH_MODE; - - // Read the -v|--verbose option increasing logging verbosity to debug. - $options = getopt("v", ["verbose", "fast"]); - if (isset($options["v"]) or isset($options["verbose"])) { - $LOGGING_VERBOSITY = LoggingVerbosity::Debug; - } - - if (isset($options["fast"])) { - $FAST_FETCH_MODE = true; - } - global $CACHE_ROOT, $ROOMS_FILE, $KNOWN_SERVERS, $KNOWN_PUBKEYS; // Create default directories with conservative permissions. diff --git a/php/generate-html.php b/php/generate-html.php index 318ed6af..638a48ba 100644 --- a/php/generate-html.php +++ b/php/generate-html.php @@ -15,26 +15,34 @@ return $files; } - foreach (rglob("$TEMPLATES_ROOT/*.php") as $phppath) { - // Do not render auxiliary PHP files. - if (str_contains("$phppath", "/+") || $phppath[0] == "+") - continue; + function generate_html() { + global $LOGGING_VERBOSITY, $TEMPLATES_ROOT, $DOCUMENT_ROOT; + $flags = LoggingVerbosity::getVerbosityFlags($LOGGING_VERBOSITY)[1]; - $docpath = str_replace($TEMPLATES_ROOT, $DOCUMENT_ROOT, $phppath); - $relpath = str_replace($TEMPLATES_ROOT, "", $phppath); - $docpath = str_replace(".php", ".html", $docpath); + foreach (rglob("$TEMPLATES_ROOT/*.php") as $phppath) { + // Do not render auxiliary PHP files. + if (str_contains("$phppath", "/+") || $phppath[0] == "+") + continue; - // This works? Yes, yes it does. - // We do this to isolate the environment and include-once triggers, - // otherwise we could include the documents in an ob_* wrapper. - // Same as shell_exec, except we don't have to escape quotes. - log_info("Generating output for $relpath."); - $document = `cd "$TEMPLATES_ROOT"; php $phppath`; + $docpath = str_replace($TEMPLATES_ROOT, $DOCUMENT_ROOT, $phppath); + $relpath = str_replace($TEMPLATES_ROOT, "", $phppath); + $docpath = str_replace(".php", ".html", $docpath); - file_put_contents($docpath, $document); + // This works? Yes, yes it does. + // We do this to isolate the environment and include-once triggers, + // otherwise we could include the documents in an ob_* wrapper. + + // Same as shell_exec, except we don't have to escape quotes. + log_info("Generating output for $relpath."); + $document = `cd "$TEMPLATES_ROOT"; php $phppath $flags`; + + file_put_contents($docpath, $document); + } + + log_info("Done generating HTML."); } - log_info("Done generating HTML."); + generate_html(); ?> diff --git a/php/utils/logging.php b/php/utils/logging.php index 3d340aa6..a4f6b36e 100644 --- a/php/utils/logging.php +++ b/php/utils/logging.php @@ -44,7 +44,7 @@ /** * Returns the color marker for the given logging verbosity. - * @param $verbosity Logging verbosity to used for printing. + * @param int $verbosity Logging verbosity to used for printing. * @return ?string Terminal escape sequence to color foreground text. */ static function getVerbosityColorMarker(int $verbosity): ?string { @@ -56,6 +56,18 @@ default => '' }; } + + /** + * Returns a pair of optíons trigerring the given verbosity. + * @param int $verbosity Logging verbosity to set using flag. + * @return string[] Pair of short and long command-line verbosity flags. + */ + static function getVerbosityFlags(int $verbosity): array { + return match($verbosity) { + LoggingVerbosity::Debug => ["-v", "--verbose"], + default => ['', ''] + }; + } } /** @@ -135,12 +147,12 @@ * Only logs when `$LOGGING_VERBOSITY` is debug and below. * @param string $msg String message to log. */ - function log_value(mixed $value) { - log_debug(var_export($value, true)); + function log_value(mixed $value, int $message_verbosity = LoggingVerbosity::Debug) { + _log_message(var_export($value, true), $message_verbosity); } /** - * @var $LOGGING_VERBOSITY + * @var int $LOGGING_VERBOSITY * Global setting. * Controls how detailed the displayed logs are. */ diff --git a/php/utils/servers-rooms.php b/php/utils/servers-rooms.php index 992f5bd6..6b45c0a8 100644 --- a/php/utils/servers-rooms.php +++ b/php/utils/servers-rooms.php @@ -1,9 +1,13 @@ $key, + $b->$key + ); + }); + } + + /** + * Sorts Community rooms in-place by their server's public key. + * @param \CommunityRoom[] $rooms Rooms to sort by server pubkey. + */ + public static function sort_rooms_by_pubkey(array &$rooms) { + usort($rooms, function(\CommunityRoom $a, \CommunityRoom $b) { + return strcmp( + $a->server->get_pubkey(), + $b->server->get_pubkey() + ); + }); + } + /** * Returns array of staff Session IDs. * @return string[] @@ -149,6 +180,32 @@ return time() - $this->created; } + /** + * Formats the period over which active users are counted as a duration string. + * @return string Active user cutoff period for this room, expressed in days. + */ + function format_user_cutoff_period(): ?string { + global $WEEK_SECONDS, $DAY_SECONDS, $HOUR_SECONDS, $MINUTE_SECONDS; + + $active_users_cutoff = $this->active_users_cutoff; + + if ($active_users_cutoff >= $WEEK_SECONDS) { + return floor($active_users_cutoff / $WEEK_SECONDS) . ' week(s)'; + } + if ($active_users_cutoff >= $DAY_SECONDS) { + return floor($active_users_cutoff / $DAY_SECONDS) . ' day(s)'; + } + if ($active_users_cutoff >= $HOUR_SECONDS) { + return floor($active_users_cutoff / $HOUR_SECONDS) . ' hour(s)'; + } + if ($active_users_cutoff >= $MINUTE_SECONDS) { + return floor($active_users_cutoff / $MINUTE_SECONDS) . 'minute(s)'; + } + + return floor($active_users_cutoff) . 's'; + + } + /** * Return the browser preview URL for this room. */ diff --git a/sites/+components/tbl_communities.php b/sites/+components/tbl_communities.php index 7d29c702..8fab8440 100644 --- a/sites/+components/tbl_communities.php +++ b/sites/+components/tbl_communities.php @@ -9,15 +9,15 @@ // Once handlers are attached in JS, this check ceases to be useful. function column_sortable($id) { // Join URL contents are not guaranteed to have visible text. - return $id != "qr" && $id != "preview" && $id != "join_url"; + return $id != "qr_code" && $id != "preview" && $id != "join_url"; } function sort_onclick($colno) { global $TABLE_COLUMNS; $column = $TABLE_COLUMNS[$colno]; $name = isset($column['name_long']) ? $column['name_long'] : $column['name']; - if (!column_sortable($column['id'])) return " title='Column: $name'"; - return " title='Click to sort by $name'"; + if (!column_sortable($column['id'])) return " title='$name'"; + return " title='Click to sort by $name'."; } // Note: Changing the names displayed requires updating @@ -28,11 +28,11 @@ ['id' => "language", 'name' => "L", 'name_long' => "Language"], ['id' => "name", 'name' => "Name"], ['id' => "description", 'name' => "About", 'name_long' => "Description"], - ['id' => "users", 'name' => "#", 'name_long' => "Weekly Active Users"], + ['id' => "users", 'name' => "#", 'name_long' => "Active Users"], ['id' => "preview", 'name' => "Preview"], - ['id' => "qr_code", 'name' => "QR"], + ['id' => "qr_code", 'name' => "QR", 'name_long' => "QR Code (for use in-app)"], ['id' => "server_icon", 'name' => "Host", 'name_long' => "Server host"], - ['id' => "join_url", 'name' => "URL", 'name_long' => "In-app Join URL"], + ['id' => "join_url", 'name' => "URL", 'name_long' => "Join URL (for use in-app)"], ]; ?> @@ -58,6 +58,7 @@ $name = html_sanitize($room->name); $desc = html_sanitize($room->description); $users = html_sanitize($room->active_users); + $users_cutoff = html_sanitize($room->format_user_cutoff_period()); $preview_link = html_sanitize($room->get_preview_url()); $join_link = html_sanitize($room->get_join_url()); $pubkey = html_sanitize($pubkey); @@ -70,15 +71,16 @@ data-hostname="" > - + - - + + - + @@ -106,11 +122,12 @@ class="qr-code-icon" src="qrcode-solid.svg" alt="Pictogram of a QR code" + title="Click here to view the QR Code for ''" >
@@ -121,8 +138,12 @@
- Copy link + Copy link
diff --git a/sites/index.php b/sites/index.php index cb205a14..1221d6c6 100644 --- a/sites/index.php +++ b/sites/index.php @@ -16,6 +16,10 @@ // List all rooms from the cached servers. $rooms = CommunityServer::enumerate_rooms($servers); + // Sort rooms by name and then host. + CommunityRoom::sort_rooms_str($rooms, 'name'); + CommunityRoom::sort_rooms_by_pubkey($rooms); + // Set the last-updated timestamp // to the time the server data file was last modified. $timestamp = filemtime($ROOMS_FILE); @@ -92,9 +96,15 @@ target="_blank" >various sources.
- We make an attempt to hide communities containing - objectionable or illegal content, but - you should still proceed with caution. + + We make an attempt to hide communities containing + objectionable or illegal content, but + you should still proceed with caution. + + + Proceed with caution when joining unofficial communities. + As JavaScript is disabled, no communities are filtered from the list. +

This site works fine without JavaScript.