Youtube feed description plugin

For youtube channel feed, ttrss can’t parse its description. I made a plugin to add thumbnail and video description as feed’s description.

In order to use this plugin, you should update ttrss newer than commit 40f4a7aa.

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

	function about() {
		return array(1.0,
			"Add youtube feed description",
			"hyg");
	}

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

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

	function hook_feed_parsed($rss) {
        if ($this->is_youtube_feed($rss)) {
            $items = $rss->get_items();
            foreach ($items as $item) {
                $this->addSummaryNode($item);
            }
        }
	}

	function api_version() {
		return 2;
	}

    private function is_youtube_feed($rss): bool {
        return strpos($rss->get_link(), 'www.youtube.com/channel') !== false;
    }

    private function addSummaryNode($item) {
        $elem = $item->get_element();
        $thumbnail_url = $elem->getElementsByTagName("thumbnail")->item(0)->getAttribute("url");
        $description = str_replace("\n", "<br>"
            , $elem->getElementsByTagName("description")->item(0)->nodeValue);
        $summary_value = "<img src=\"$thumbnail_url\"/><br>$description";
        $summary_node = $elem->ownerDocument->createElement("summary", str_replace("&", "&amp;", $summary_value));
        $elem->appendChild($summary_node);
    }

}

I already get descriptions and full videos in my youtube feeds…? maybe I’m thinking of titles.

You should probably point out that your code contains a scalar type hint and will require PHP7.

Does anyone have an updated version of this plugin that’s compatible with the current version of the hook_feed_parsed function? Alternatively, an example of a current plugin using hook_feed_parsed? This one no longer works and just results in PHP errors when enabled, which is a shame as it seems very useful.

just add feed_id to the definition

function hook_feed_parsed($parser, $feed_id) {

OK, great, does that mean I then need to substitute the instances of $rss within the function with $feed_id now, or will $rss still work here? Sorry, not much of a coder, so just hacking this together!

EDIT: FWIW I tried both without changing the rest of the plugin (errors about undefined var) and changing all instances to $feed_id (errors about get_link not working on an int), so it doesn’t look like this can be easily done with just a function definition change?

Looks like this is working:

<?php
class Youtube_Description extends Plugin {
    function about() {
        return [
            1.1,
            'Add YouTube feed description',
            'hyg',
        ];
    }

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

    /**
     * @param FeedParser $parser
     * @param int $feed_id
     * @return void
     */
    function hook_feed_parsed($parser, $feed_id) {
        if ($this->is_youtube_feed($parser->get_link())) {
            $items = $parser->get_items();
            foreach ($items as $item) {
                $this->add_summary_node($item);
            }
        }
    }

    function api_version() {
        return 2;
    }

    private function is_youtube_feed(string $link): bool {
        return strpos($link, 'www.youtube.com/channel') !== false;
    }

    private function add_summary_node(FeedItem_Common $item): void {
        $elem = $item->get_element();

        /** @var array<string> */
        $content = [];

        /** @var ?DOMElement */
        $thumbnail = $elem->getElementsByTagName('thumbnail')->item(0);

        if ($thumbnail) {
            $content[] = "<img src=\"{$thumbnail->getAttribute('url')}\"/>";
        }

        /** @var ?DOMElement */
        $description = $elem->getElementsByTagName('description')->item(0);

        if ($description) {
            $content[] = str_replace('\n', '<br/>', $description->nodeValue);
        }

        $summary_node = $elem->ownerDocument->createElement(
            'summary',
            str_replace('&', '&amp;', implode('<br/>', $content)),
        );

        if ($summary_node) {
            $elem->appendChild($summary_node);
        }
    }
}
1 Like

Ahh, that worked perfectly, thanks for the fixed version!