You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
sessioncommunities.online/php/generate-listings.php

149 lines
4.1 KiB
PHP

<?php
/**
* \file
* Implement Community listings for the [Listing Provider API](https://codeberg.org/gravel/session-listing-providers).
*/
require_once "getenv.php";
require_once "utils/logging.php";
require_once "servers/servers-rooms.php";
/**
* Represents a Community listing in the Listing Provider API.
*/
class CommunityListing implements JsonSerializable {
/**
* @var string $id
* Unique listing identifier.
*/
public readonly string $id;
/**
* @var string $name
* Human-readable listing name.
*/
public readonly string $name;
/**
* @var string $rating
* One-word content rating for Communities listed.
*/
public readonly string $rating;
/**
* @var CommunityRoom[] $rooms
* Communities included in the listing.
*/
public readonly array $rooms;
/**
* Create a new CommunityListing instance with the given parameters.
* @param string $id Unique listing identifier.
* @param string $name Human-readable listing name.
* @param string $rating One-word content rating for Communities listed.
* @param CommunityRoom[] $rooms Communities included in the listing.
*/
public function __construct(string $id, string $name, ?string $rating, array $rooms) {
$this->id = $id;
$this->name = $name;
$this->rating = $rating ?? "unknown";
$this->rooms = $rooms;
}
/**
* Produce associative listing data for JSON serialization.
*/
public function jsonSerialize(): mixed {
// TODO: Careful serialization
$details = get_object_vars($this);
$details['rooms'] = array_map(function(CommunityRoom $room){
return $room->to_listing_data();
}, $this->rooms);
return $details;
}
/**
* Produce associative data summarizing this listing.
*/
public function to_summary(): array {
return array(
'id' => $this->id,
'name' => $this->name,
'rating' => $this->rating,
'rooms' => count($this->rooms)
);
}
}
/**
* Construct Community listings from listing configuration and cached Communities.
* @return CommunityListing[]
* \todo Refactor
*/
function resolve_listings_config(): array {
global $LISTINGS_INI, $ROOMS_FILE;
$listings_raw = parse_ini_file($LISTINGS_INI, process_sections: true, scanner_mode: INI_SCANNER_RAW);
$servers_raw = file_get_contents($ROOMS_FILE);
$server_data = json_decode($servers_raw, true);
$servers = CommunityServer::from_details_array($server_data);
$rooms_all = CommunityServer::enumerate_rooms($servers);
$listings = [];
foreach ($listings_raw as $id => $listing_props) {
$filter = [...($listing_props['rooms'] ?? []), ...($listing_props['sogs'] ?? [])];
$matchees = [];
$rooms = CommunityRoom::select_rooms($rooms_all, $filter, $matchees);
foreach ($filter as $filter_item) {
if (!in_array($filter_item, $matchees)) {
log_warning("Could not find $filter_item from listing $id.");
}
}
$rooms = array_filter($rooms, function(CommunityRoom $room) {
return !$room->is_off_record();
});
$listings[] = new CommunityListing(
$id,
$listing_props['name'],
$listing_props['rating'],
$rooms
);
}
return $listings;
}
/**
* Resolve and write configured Community listings to disk.
*/
function generate_listings() {
global $LISTING_PROVIDER_LISTING_SUMMARY, $LISTING_PROVIDER_LISTINGS;
log_info("Generating listings...");
$listings_resolved = resolve_listings_config();
$summaries = array_map(function(CommunityListing $listing) {
return $listing->to_summary();
}, $listings_resolved);
file_put_contents($LISTING_PROVIDER_LISTING_SUMMARY, json_encode($summaries));
foreach ($listings_resolved as $listing) {
$id = $listing->id;
file_put_contents(
"$LISTING_PROVIDER_LISTINGS/$id",
json_encode($listing)
);
}
$listings_count = count($listings_resolved);
log_info("Generated $listings_count listings.");
}
file_exists($LISTING_PROVIDER_LISTINGS) or mkdir($LISTING_PROVIDER_LISTINGS, 0755, true);
$options = getopt("v", ["verbose"]);
if (isset($options["v"]) or isset($options["verbose"])) {
$LOGGING_VERBOSITY = LoggingVerbosity::Debug;
}
generate_listings();
?>