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/assets/room-icons.php

128 lines
3.8 KiB
PHP

<?php
require_once 'servers/known-servers.php';
/**
* Return local path to room icon.
* @param string $room_id Id of room to locate icon for.
*/
function room_icon_path(string $room_id): string {
global $ROOM_ICONS_CACHE;
return "$ROOM_ICONS_CACHE/$room_id";
}
/**
* Return local path to resized room icon.
* @param string $room_id Id of room to locate icon for.
* @param string $size Image dimensions.
*/
function room_icon_path_resized(string $room_id, string $size): string {
global $ROOM_ICONS;
return "$ROOM_ICONS/$room_id-$size";
}
/**
* Return server path to room icon.
* @param string $room_id Id of room to locate icon for.
* @param string $size Image dimensions.
*/
function room_icon_path_relative(string $room_id, string $size): string {
global $ROOM_ICONS_RELATIVE;
return "$ROOM_ICONS_RELATIVE/$room_id-$size";
}
/**
* @return \Generator<int,CurlHandle,CurlHandle|false,void>
*/
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);
?>