*/ function fetch_room_icon_coroutine(\CommunityRoom $room): Generator { if (room_icon_safety($room) < 0) { return; } $room_id = $room->get_room_identifier(); $icon_cached = room_icon_path($room_id); $icon_expired = file_exists($icon_cached) && filemtime($icon_cached) < strtotime("-1 day"); // Re-fetch icons periodically. if (!file_exists($icon_cached) || $icon_expired) { $icon_url = $room->get_icon_url(); if (empty($icon_url)) { return null; } log_debug("Fetching icon for $room_id."); $icon_response = yield from FetchingCoroutine::from_url($icon_url)->run(); $icon = $icon_response ? curl_multi_getcontent($icon_response) : null; if (empty($icon)) { log_info("$room_id returned an empty icon."); } // Never overwrite with an empty file. if (!(file_exists($icon_cached) && filesize($icon_cached) > 0 && empty($icon))) { file_put_contents($icon_cached, $icon); } } } /** * Fetch the icon of the given room and return its relative path. * @param \CommunityRoom $room * @param string $size Image dimensions. * @return string Relative path or null if icon is absent. */ function room_icon(\CommunityRoom $room, string $size): ?string { list($width, $height) = explode("x", $size); $width = intval($width); $height = intval($height); assert(!empty($width) && !empty($height)); if (room_icon_safety($room) < 0) { return null; } $room_id = $room->get_room_identifier(); $icon_cached = room_icon_path($room_id); $icon_resized = room_icon_path_resized($room_id, $size); $icon_expired = file_exists($icon_cached) && filemtime($icon_cached) < strtotime("-1 day"); if (!file_exists($icon_cached)) { log_debug("Missing icon asset for $room_id"); return ""; } if (!file_exists($icon_resized) || $icon_expired) { $icon_cached_contents = file_get_contents($icon_cached); if (empty($icon_cached_contents)) { file_put_contents($icon_resized, ""); return ""; } // Resize image $gd_image = imagecreatefromstring($icon_cached_contents); $gd_resized = imagescale($gd_image, $width, $height); if (!imagewebp($gd_resized, $icon_resized)) { log_info("Converting image for $room_id to $size failed"); } } if (filesize($icon_resized) == 0) { return ""; } return room_icon_path_relative($room_id, $size); } function room_icon_safety(\CommunityRoom $room): int { global $ICON_ALLOWLIST, $ICON_BLOCKLIST; if (in_array($room->get_room_identifier(), $ICON_BLOCKLIST)) { return -1; } if (in_array($room->server->get_hostname(), $ICON_ALLOWLIST)) { return 1; } if (in_array($room->server->get_hostname(), $ICON_BLOCKLIST)) { return -1; } if ($room->has_nsfw_keywords()) { return -1; } return 0; } file_exists($ROOM_ICONS_CACHE) or mkdir($ROOM_ICONS_CACHE, 0755, true); file_exists($ROOM_ICONS) or mkdir($ROOM_ICONS, 0755, true); ?>