Broken plugin functionality after recent update

Are you using stock Docker compose setup?

No, but using docker compose (current master, 75d1291976) setup give same results (manually created plugin inside plugin.local at persistent volume location to test and import my opml).

Current setup is using, ttrss d6de021ae, nginx 1.18, postgresql 13.1


Describe the problem you’re having:

I using my ttrss as youtube aggreator, and long time ago I’ve found useful plugin to grab thumbnail of a video from youtube and present it instead of article in ttrss. After commit 82adb0130 this functionality not longer works (probably become plugin using HOOK_RENDER_ENCLOSURE

Example how it was working on 0fbf10991 (upper part of the image)
Example how it working now on d6de021ae (lower part of the image):

plugin source:

<?php
class Me_Youtube_Thumbnail extends Plugin {
	private $host;

	function about() {
		return array(1.0,
			"Thumbnails from videos in Youtube RSS feeds",
			"me");
	}

	function init($host) {
		$this->host = $host;

		$host->add_hook($host::HOOK_RENDER_ENCLOSURE, $this);
	}

	function hook_render_enclosure($entry, $hide_images) {

		$matches = array();

		if (preg_match("/\/\/www\.youtube\.com\/v\/([\w-]+)/", $entry["url"], $matches) ||
			preg_match("/\/\/www\.youtube\.com\/watch?v=([\w-]+)/", $entry["url"], $matches) ||
			preg_match("/\/\/youtu.be\/([\w-]+)/", $entry["url"], $matches)) {

			$vid_id = $matches[1];
			
			$img_stub = '<img width="75%" src="https://img.youtube.com/vi/';			
			$full_html = "";			
			for ($x = 0; $x <= 0; $x++) {				
				$full_html = $full_html . $img_stub . $vid_id. '/' . 'sddefault.jpg"></img>';
			} 			

			return $full_html ;
		}
	}

	function api_version() {
		return 2;
	}
}
?>

Any way to fix this? Thanks in advance.

I got the same problem and after restarting I found out the api resize plugin was the source of trouble because it was dublicated on my system. Removing one of them fixed the problem

Which plugin is that? I have very few plugins actually enabled:

  • auth_internal
  • af_comics
  • af_readability
  • hl_legacy
  • note
  • and me_youtube_thumbnail mentioned above.

If you are talking about Git repository browser - I’m not using it / doesn’t have it.

Try this (disclaimer: lightly tested and could be improved):

<?php
class Me_Youtube_Thumbnail extends Plugin {
  private $host;

  function about() {
    return [
      2.0,
      'Thumbnails from videos in Youtube RSS feeds',
      'me',
    ];
  }

  function init($host) {
    $this->host = $host;
    $host->add_hook($host::HOOK_FORMAT_ENCLOSURES, $this);
  }

  function hook_format_enclosures($enclosures_formatted, $enclosures, $id, $always_display_enclosures, $article_content, $hide_images) {
    foreach ($enclosures as $enclosure) {
      if (preg_match('#//www\.youtube\.com/v/([\w-]+)#', $enclosure['content_url'], $matches) ||
        preg_match('#//www\.youtube\.com/watch?v=([\w-]+)#', $enclosure['content_url'], $matches) ||
        preg_match('#//youtu.be/([\w-]+)#', $enclosure['content_url'], $matches)) {
          $enclosures_formatted .= "<img width='75%' src='https://img.youtube.com/vi/{$matches[1]}/sddefault.jpg'><br>";
      }
      else {
        $enclosures_formatted .= $enclosure['content_url'] . '<br>';
      }
    }
    return $enclosures_formatted;
  }

  function api_version() {
    return 2;
  }
}

Working beautifully, thank you!

yep this is no longer a thing because enclosures are rendered on the client, maybe this hook should be reintroduced on the javascript side. i’ll think about it.

Is there a recommended way to approach this now? I just spent a while implementing a plugin that used HOOK_RENDER_ENCLOSURE on the server side (still works as of 6738f5c86, 2022-02-05). I can do the same thing on the client side by forking js/Article.js, but how would I do it in a plugin? Would you advise just manipulating the DOM after it’s been written?

Edit: specifically, I’d like to be able to over-ride the way enclosures are rendered under certain circumstances, and hand off to the default rendering in all others.

HOOK_RENDER_ENCLOSURE has been reimplemented as of https://git.tt-rss.org/fox/tt-rss/commit/33fff2686946021314a24feef61032beaf48e7a4.

that’s pretty much https://git.tt-rss.org/fox/ttrss-youtube-thumb etc.

Thank you – yes, I’d been using that for inspiration. The problem I’m facing is that I have a built-in plugin already activated (af_youtube_embed) that also uses HOOK_RENDER_ENCLOSURE, and depending on how I order the plugins lexically, only the second one works… i.e. if my plugin is loaded after af_youtube_embed then the built-in plugin doesn’t load; if my plugin comes first (suppose I name it aa_my_plugin) then my plugin doesn’t work (but the built-in one does). Each works as expected when it’s the only one registering HOOK_RENDER_ENCLOSURE. Is there a trick to registering this hook with more than one plugin?

Thank you so much!

backend hook system has priorities, you could try playing with those.

renaming your plugin should also work, just make sure class name matches and enable it again.

Thank you again for your response :slight_smile:

I can control the priority easily enough, but I kinda want both of the hooks to be called (as with the built-in af_youtube_embed plugin, mine sniffs the content to decide whether to render some custom HTML or not. I’m working on something that is only applicable to podcasts/audio). Is that not possible?

the way i remember it, each enclosure may be custom rendered once, if there’s no html then built-in rendering takes over. plugins shouldn’t prevent each other unless they select same enclosures to work on.

https://git.tt-rss.org/fox/tt-rss/src/branch/master/classes/article.php#L343

try debugging to see what actually happens when your plugin is run.