'https://raw.githubusercontent.com/GNU-Linux-libre/Awesome-Session-Group-List/main/README.md', 'LOKI' => 'https://lokilocker.com/Mods/Session-Groups/wiki/Session-Open-Groups', 'SDIR' => 'https://session.directory/?all=groups', 'SDIR-BASE' => 'https://session.directory/', 'SDIR-PATTERN' => '/view_session_group_user_lokinet\.php\?id=\d+/', 'SDIR-JSON' => 'https://session.directory/scrape.php', 'FARK' => 'https://freearkham.cc/' ); private string $contents_aggregated = ""; private string $contents_sdir = ""; private array $room_tags; /** * Fetches and saves known sources of Session Community join links. */ public function __construct() { global $SOURCES; log_info("Requesting Awesome Session Group list..."); $contents_asgl = file_get_contents(CommunitySources::SOURCES['ASGL']); log_debug($http_response_header[0]); // Supposed to be "HTTP/1.1 200 OK" log_info("Requesting Lokilocker Mods Open Group list..."); $contents_loki = file_get_contents(CommunitySources::SOURCES['LOKI']); log_debug($http_response_header[0]); // Supposed to be "HTTP/1.1 200 OK" log_info("Requesting session.directory list..."); $this->contents_sdir = file_get_contents(CommunitySources::SOURCES['SDIR-JSON']); log_debug($http_response_header[0]); // Supposed to be "HTTP/1.1 200 OK" if (!$this->sdir_process_tags()) { log_debug(truncate($this->contents_sdir, 50)); log_error("Could not parse tags from session.directory."); } log_info("Requesting FreeArkham.cc list..."); $contents_fark = file_get_contents(CommunitySources::SOURCES['FARK']); log_debug($http_response_header[0]); // Supposed to be "HTTP/1.1 200 OK" log_info('Done fetching sources.'); $this->contents_aggregated = $contents_asgl . $contents_fark . $contents_loki . $this->contents_sdir; } private static function preprocess_tag(?string $tag) { $tag = trim($tag); if (strlen($tag) == 0) { return $tag; } $tag = html_sanitize(html_entity_decode($tag)); if ($tag[0] == '#') { return substr($tag, 1); } return $tag; } private function sdir_process_tags(): bool { $entry_missing_url = false; $entry_missing_tags = false; try { $rooms = json_decode($this->contents_sdir, true, 512, JSON_THROW_ON_ERROR); } catch (JsonException) { return false; } foreach ($rooms as $room_entry) { // TODO: Check types if (!isset($room_entry['url'])) { log_value($room_entry); $entry_missing_url = true; continue; } if (!isset($room_entry['tags'])) { log_value($room_entry); $entry_missing_tags = true; continue; } $url = $room_entry['url']; $tags = explode(',', $room_entry['tags']); $room_token = url_get_token($url); $pubkey = url_get_pubkey($url); $pubkey_4 = substr($pubkey, 0, 4); $room_id = "$room_token+$pubkey_4"; $tags = array_map(function(?string $tag) { return CommunitySources::preprocess_tag($tag); }, $tags); $tags = array_filter( $tags, function(?string $tag) { return strlen($tag) != 0; } ); $this->room_tags[$room_id] = $tags; } if ($entry_missing_url) { log_error("One or more room entries from session.directory is missing the 'url' parameter."); } if ($entry_missing_tags) { log_error("One or more room entries from session.directory is missing the 'tags' parameter."); } return true; } /** * Returns all join URLs found. * @return string[] Join URLs. */ function get_join_urls(): array { return array_unique( parse_join_links($this->contents_aggregated) ); } /** * Return known tags for the given room. * @param string $room_id Room identifier. * @return string[] Array of string tags. */ function get_room_tags($room_id): array { if (!isset($this->room_tags[$room_id])) { return []; } return array_slice($this->room_tags[$room_id], 0); } } ?>