Plugin: Slashdot cleanup

Post plugins and custom CSS snippets here
GravityWell
Bear Rating Trainee
Bear Rating Trainee
Posts: 10
Joined: 13 Apr 2013, 01:48

Plugin: Slashdot cleanup

Postby GravityWell » 15 Apr 2013, 01:40

Hi,

First I'd like to thank the dev(s) for their work on TTRSS. I'm a Google Reader refugee, and fortunately I have enough development skills to take advantage of this awesome work.

I made a plugin to clean up the Slashdot RSS feed in combined mode. It removes the huge comments iframe and the rest of the noise, which reduces the size significantly, and looks much better IMO. This was also an effort to make a minimal plugin with just the necessary code to clean up articles, which is my typical use case. I'm interested in any comments.

I don't know how moderation will go on my first post, so I'll just use code tags.

Create a folder plugins\af_slashdot and create a file named init.php:
NOTE: Updated to work with 1.7.9

Code: Select all

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

   function about() {
      return array(1.1,
         "Slashdot cleanup",
         "GravityWell",
         false,
         "http://tt-rss.org/forum/viewtopic.php?f=22&t=1836");
   }

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

      $host->add_hook($host::HOOK_RENDER_ARTICLE_CDM, $this);
   }
   
   function api_version() {
      return 2;
   }
   
   function hook_render_article_cdm($article) {

      if ( strpos($article["link"], "rss.slashdot.org") !== FALSE ) {
         $newvar = preg_replace( '@<div> <a href="http://twitter.*@', "</body></html>" , $article["content"] );
         $article["content"] = $newvar;
      }
      return $article;
   }
}
?>
Last edited by GravityWell on 19 May 2013, 04:28, edited 2 times in total.

GravityWell
Bear Rating Trainee
Bear Rating Trainee
Posts: 10
Joined: 13 Apr 2013, 01:48

Re: Plugin: Slashdot cleanup

Postby GravityWell » 15 Apr 2013, 02:08

Here is a screenshot of what this plugin does:

sdot.png
sdot.png (28.15 KiB) Viewed 8097 times

phz
Bear Rating Disaster
Bear Rating Disaster
Posts: 77
Joined: 18 Mar 2013, 18:32

Re: Plugin: Slashdot cleanup

Postby phz » 15 Apr 2013, 09:14

I have been running the following script to clean up Slashdot feeds. It gives similar results, but I wanted to keep the iframe with the comments, though. The script is over-the-top commented to explain what it does:

Code: Select all

<?php
class Af_Slashdot extends Plugin {

    private $link;
    private $host;

    function about() {
        return array(1.0,
            'Correctly sized iframe insertions in Slashdot posts',
            'dandersson',
            false);
    }

    function init($host) {
        // Boilerplate to register hooks.
        $this->link = $host->get_link();
        $this->host = $host;

        $host->add_hook($host::HOOK_ARTICLE_FILTER, $this);
    }
   
    function hook_article_filter($article) {
        $owner_uid = $article['owner_uid'];

        // Only match Slashdot posts. Select by item link target.
        if (strpos($article['link'], 'slashdot.org/') !== FALSE) {
            // This string will be saved in the `plugin_data` field in the
            // database for the corresponding item after applying the filter. 
            // By checking for the existence of this value, we make sure the
            // filter isn't applied everytime the items are loaded.
            $plugin_string = 'af_slashdot,' . $owner_uid . ':';

            if (strpos($article['plugin_data'], $plugin_string) === FALSE) {
                $doc = new DOMDocument();
                @$doc->loadHTML($article['content']);

                if ($doc) {
                    $ps = $doc->getElementsByTagName('p');
                    // Only keep first paragraph (that's where the summary is,
                    // the rest is just cruft).
                    while ($ps->item(1)) {
                        $ps->item(1)->parentNode->removeChild($ps->item(1));
                    }

                    // Keep the iframe with the comments. Set width and height
                    // since style attributes are stripped.
                    $iframe = $doc->getElementsByTagName('iframe')->item(0);
                    $iframe->setAttribute('width', '100%');
                    $iframe->setAttribute('height', '324');

                    // Remove G+/FB/Twitter/etc. images and unnecessary links. 
                    // Might be easier to just fetch the summary and comments
                    // and build a completely new DOMObject to discard
                    // everything else.
                    $search = new DomXPath($doc);
                    $tags = $search->query('//div|//img|//a|//br');
                    foreach ($tags as $tag) {
                        $tag->parentNode->removeChild($tag);
                    }

                    $body = $doc->getElementsByTagName('body')->item(0);

                    // If we fail to find this element, something has gone
                    // awry. Then do nothing and just return $article as it
                    // was. Else, write the new content to the database.
                    if ($body) {
                            $article['content'] = $doc->saveXML($body, LIBXML_NOEMPTYTAG);
                            $article['plugin_data'] = $plugin_string . $article['plugin_data'];
                    }
                }
            } else if (isset($article['stored']['content'])) {
                $article['content'] = $article['stored']['content'];
            }
        }
        return $article;
    }
}
?>


As noted it might be easier to just create a new DOM and explicitly only include the first paragraph and the iframe, but since I used this script as a boilerplate for other feed plugins, I did it this way.

GravityWell
Bear Rating Trainee
Bear Rating Trainee
Posts: 10
Joined: 13 Apr 2013, 01:48

Re: Plugin: Slashdot cleanup

Postby GravityWell » 15 Apr 2013, 19:24

Nice, this shows some advanced techniques. I see you're using HOOK_ARTICLE_FILTER. I'm still not clear on the different hook types, but I know HOOK_RENDER_ARTICLE_CDM works at display time. I guess HOOK_ARTICLE_FILTER works at the time the article is initially downloaded, or both? I still have a lot to learn, but I'm glad that I'm able to customize feeds.

tbar
Bear Rating Trainee
Bear Rating Trainee
Posts: 18
Joined: 16 Apr 2013, 09:39

Re: Plugin: Slashdot cleanup

Postby tbar » 24 Apr 2013, 12:23

phz wrote:It gives similar results, but I wanted to keep the iframe with the comments, though.


I like your version better but I don't want the iframe with the comments. I've therefore changed the following in your plugin:

Code: Select all

                    // Keep the iframe with the comments. Set width and height
                    // since style attributes are stripped.
                    $iframe = $doc->getElementsByTagName('iframe')->item(0);
                    $iframe->setAttribute('width', '100%');
                    $iframe->setAttribute('height', '324');

to this:

Code: Select all

                    // Remove the iframe with the comments.
                    $iframe = $doc->getElementsByTagName('iframe');
                    while ($iframe->item(0)) {
                      $iframe->item(0)->parentNode->removeChild($iframe->item(0));
                    }

craywolf
Mr. Awesome
Posts: 97
Joined: 19 Mar 2013, 18:07

Re: Plugin: Slashdot cleanup

Postby craywolf » 25 Apr 2013, 18:22

GravityWell's plugin updated to work with TT-RSS 1.7.8+. Untested, but it's a simple change, should be fine:

Code: Select all

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

   function about() {
      return array(1.1,
         "Slashdot cleanup",
         "GravityWell",
         false,
         "http://tt-rss.org/forum/viewtopic.php?f=22&t=1836");
   }

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

      $host->add_hook($host::HOOK_RENDER_ARTICLE_CDM, $this);
   }
   
   function api_version() {
      return 2;
   }
   
   function hook_render_article_cdm($article) {

      if ( strpos($article["link"], "rss.slashdot.org") !== FALSE ) {
         $newvar = preg_replace( '@<div> <a href="http://twitter.*@', "</body></html>" , $article["content"] );
         $article["content"] = $newvar;
      }
      return $article;
   }
}
?>


phz wrote:I have been running the following script to clean up Slashdot feeds. It gives similar results, but I wanted to keep the iframe with the comments, though. The script is over-the-top commented to explain what it does:


I've been using this version of the plugin. Here's the fixed version of this one:

Code: Select all

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

    function about() {
        return array(1.1,
            'Correctly sized iframe insertions in Slashdot posts',
            'dandersson',
            false,
            "http://tt-rss.org/forum/viewtopic.php?f=22&t=1836");
    }

    function init($host) {
        // Boilerplate to register hooks.
        $this->host = $host;

        $host->add_hook($host::HOOK_ARTICLE_FILTER, $this);
    }
   
   function api_version() {
      return 2;
   }

    function hook_article_filter($article) {
        $owner_uid = $article['owner_uid'];

        // Only match Slashdot posts. Select by item link target.
        if (strpos($article['link'], 'slashdot.org/') !== FALSE) {
            // This string will be saved in the `plugin_data` field in the
            // database for the corresponding item after applying the filter.
            // By checking for the existence of this value, we make sure the
            // filter isn't applied everytime the items are loaded.
            $plugin_string = 'af_slashdot,' . $owner_uid . ':';

            if (strpos($article['plugin_data'], $plugin_string) === FALSE) {
                $doc = new DOMDocument();
                @$doc->loadHTML($article['content']);

                if ($doc) {
                    $ps = $doc->getElementsByTagName('p');
                    // Only keep first paragraph (that's where the summary is,
                    // the rest is just cruft).
                    while ($ps->item(1)) {
                        $ps->item(1)->parentNode->removeChild($ps->item(1));
                    }

                    // Keep the iframe with the comments. Set width and height
                    // since style attributes are stripped.
                    $iframe = $doc->getElementsByTagName('iframe')->item(0);
                    $iframe->setAttribute('width', '100%');
                    $iframe->setAttribute('height', '324');

                    // Remove G+/FB/Twitter/etc. images and unnecessary links.
                    // Might be easier to just fetch the summary and comments
                    // and build a completely new DOMObject to discard
                    // everything else.
                    $search = new DomXPath($doc);
                    $tags = $search->query('//div|//img|//a|//br');
                    foreach ($tags as $tag) {
                        $tag->parentNode->removeChild($tag);
                    }

                    $body = $doc->getElementsByTagName('body')->item(0);

                    // If we fail to find this element, something has gone
                    // awry. Then do nothing and just return $article as it
                    // was. Else, write the new content to the database.
                    if ($body) {
                            $article['content'] = $doc->saveXML($body, LIBXML_NOEMPTYTAG);
                            $article['plugin_data'] = $plugin_string . $article['plugin_data'];
                    }
                }
            } else if (isset($article['stored']['content'])) {
                $article['content'] = $article['stored']['content'];
            }
        }
        return $article;
    }
}
?>


GravityWell
Bear Rating Trainee
Bear Rating Trainee
Posts: 10
Joined: 13 Apr 2013, 01:48

Re: Plugin: Slashdot cleanup

Postby GravityWell » 26 Apr 2013, 17:27

@craywolf: Thanks for the update. I'll add your changes to the first post when the next "official" release comes out which I guess is 1.7.9. That will be my first experience with a version upgrade.

craywolf
Mr. Awesome
Posts: 97
Joined: 19 Mar 2013, 18:07

Re: Plugin: Slashdot cleanup

Postby craywolf » 26 Apr 2013, 17:33

GravityWell wrote:@craywolf: Thanks for the update. I'll add your changes to the first post when the next "official" release comes out which I guess is 1.7.9. That will be my first experience with a version upgrade.


Cheers. The update is no big deal. Just deleted the two lines referencing $link, and added the api_version() function. I also put a link to this thread in the "more info" section of about() and bumped the version number.

pjackson
Bear Rating Trainee
Bear Rating Trainee
Posts: 1
Joined: 31 Mar 2014, 14:36

Re: Plugin: Slashdot cleanup

Postby pjackson » 31 Mar 2014, 17:50

Code: Select all

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

   function about() {
      return array(1.1,
         "Slashdot cleanup",
         "GravityWell",
         false,
         "http://tt-rss.org/forum/viewtopic.php?f=22&t=1836");
   }

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

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

   function api_version() {
      return 2;
   }

   function hook_render_article_cdm($article) {

      if ( strpos($article["link"], "rss.slashdot.org") !== FALSE ) {
         $newvar = preg_replace( '@<div> <a href="http://twitter.*@', "</body></html>" , $article["content"] );
         $article["content"] = $newvar;
      }
      return $article;
   }
}
?>


Sorry, i know close to no php. I copied the snipped above in /usr/share/tt-rss/www/plugins/af_slashdot/init.php and then activated it on preferences/plugins but it does nothing. i checked that my url for the feed includes "rss.slashdot.org" (its as much as i can read from code snipped)

I tried the one with the hooks with similar results. I know that tt-rss is recognizing it at least because i can activate them in preferences but not sure why is not working

Im running 1.11 version of tt-rss

I tried to debug it, but not sure where to look. Any help with this plugin?
Thanks


Return to “Themes and plugins”

Who is online

Users browsing this forum: No registered users and 8 guests