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.
		
		
		
		
		
			
		
			
				
	
	
		
			114 lines
		
	
	
		
			3.5 KiB
		
	
	
	
		
			PHP
		
	
			
		
		
	
	
			114 lines
		
	
	
		
			3.5 KiB
		
	
	
	
		
			PHP
		
	
| <?php
 | |
| 	/**
 | |
| 	 * \file
 | |
| 	 * Implement the fetching of Community room icons.
 | |
| 	 */
 | |
| 
 | |
| 	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 web-facing 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";
 | |
| 	}
 | |
| 
 | |
| 	/**
 | |
| 	 * Fetch the icon of a Community and yield required network requests.
 | |
| 	 * @param CommunityRoom $room Community to fetch icon for.
 | |
| 	 * @return Generator<int,CurlHandle,CurlHandle|false,void>
 | |
| 	 */
 | |
| 	function fetch_room_icon_coroutine(CommunityRoom $room): Generator {
 | |
| 		$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);
 | |
| 			}
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	/**
 | |
| 	 * Resize a fetched 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() < 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);
 | |
| 	}
 | |
| 
 | |
| 	file_exists($ROOM_ICONS_CACHE) or mkdir($ROOM_ICONS_CACHE, 0755, true);
 | |
| 	file_exists($ROOM_ICONS) or mkdir($ROOM_ICONS, 0755, true);
 | |
| ?>
 |