src/Tweeper.php: fix rendering Instagram images in some feed readers
authorAntonio Ospite <ao2@ao2.it>
Sun, 2 Jan 2022 21:44:39 +0000 (22:44 +0100)
committerAntonio Ospite <ao2@ao2.it>
Sun, 2 Jan 2022 21:44:39 +0000 (22:44 +0100)
Instagram.com is using Cross Origin Resource Policy and this prevents
images in RSS items from being displayed in the Web view of some feed
readers like Liferea.

Add a function to generate Data URLs with base64 payloads and use that
for instagram images a s a workaround to fix rendering images in some
feed readers.

src/Tweeper.php
src/rss_converter_instagram.com.xsl

index f79bb08..2d3870f 100644 (file)
@@ -234,6 +234,34 @@ class Tweeper {
   }
 
   /**
+   * Generate a data URL.
+   */
+  public static function generateDataURL($url) {
+    $supported_content_types = [
+      "image/gif",
+      "image/jpeg",
+      "image/png",
+    ];
+
+    $url_info = Tweeper::getUrlInfo($url);
+    if (FALSE === $url_info) {
+      trigger_error("Failed to retrieve info for URL: " . $url, E_USER_WARNING);
+      return '';
+    }
+
+    $supported = in_array($url_info['content_type'], $supported_content_types);
+    if (!$supported) {
+      trigger_error("Unsupported data URL type \"" . $url_info['content_type'] . "\" for URL: " . $url_info['url'], E_USER_WARNING);
+      return '';
+    }
+
+    $base64Data = base64_encode(file_get_contents($url));
+    $dataURL = 'data: ' . $url_info['content_type'] . ';base64,' . $base64Data;
+
+    return $dataURL;
+  }
+
+  /**
    * Mimic the message from libxml.c::php_libxml_ctx_error_level()
    */
   private static function logXmlError($error) {
index 855ce0b..71b60a7 100644 (file)
@@ -66,6 +66,7 @@
 
     <xsl:template match="//edges/node">
         <xsl:variable name="item-content-image" select="./display_url"/>
+        <xsl:variable name="item-content-image-data" select="php:functionString('Tweeper\Tweeper::generateDataURL', $item-content-image)"/>
         <xsl:variable name="item-content-caption" select="./edge_media_to_caption/edges/node/text"/>
         <xsl:variable name="item-permalink" select="concat($BaseURL, '/p/', ./shortcode, '/')"/>
         <item>
                     <xsl:value-of select="$item-content-caption"/>
                 </p><br />
                 <xsl:if test="$show-multimedia = 1">
-                    <a href="{$item-permalink}"><img src="{$item-content-image}" style="max-width: 100%"/></a>
+                    <a href="{$item-permalink}"><img src="{$item-content-image-data}" style="max-width: 100%"/></a>
                 </xsl:if>
                 <xsl:text disable-output-escaping="yes">]]&gt;</xsl:text>
             </description>