proper readme file
Peter Molnar hello@petermolnar.eu
Thu, 16 Jul 2015 11:01:17 +0100
2 files changed,
128 insertions(+),
25 deletions(-)
M
blogroll2email.php
→
blogroll2email.php
@@ -27,26 +27,44 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/ class blogroll2email { + // 30 mins is reasonable const revisit_time = 1800; const schedule = 'blogroll2email'; - var $schedule = null; - + /** + * thing to run as early as possible + */ public function __construct () { + // this is mostly for debugging reasons register_activation_hook( __FILE__ , array( &$this, 'plugin_activate' ) ); + // clear schedules if there's any on deactivation register_deactivation_hook( __FILE__ , array( &$this, 'plugin_deactivate' ) ); + // add_action( 'init', array( &$this, 'init')); + // extend current cron schedules with our entry add_filter( 'cron_schedules', array(&$this, 'add_cron_schedule' )); + // re-enable the links manager + add_filter( 'pre_option_link_manager_enabled', '__return_true' ); + // add our own action for the scheduler to call it + add_action( static::schedule, array( &$this, 'worker' ) ); } + /** + * things to run within WordPress init + */ public function init () { - // additional cron schedules - add_action( static::schedule, array( &$this, 'worker' ) ); if (!wp_get_schedule( static::schedule )) wp_schedule_event ( time(), static::schedule, static::schedule ); return false; } + /** + * add our own schedule + * + * @param array $schedules - current schedules list + * + * @return array $schedules - extended schedules list + */ public function add_cron_schedule ( $schedules ) { $schedules[ static::schedule ] = array(@@ -59,7 +77,7 @@ }
/** - * activation hook function, to be extended + * activation hook function */ public function plugin_activate() { self::debug('activating');@@ -67,7 +85,7 @@
} /** - * deactivation hook function, to be extended + * deactivation hook function; clears schedules */ public function plugin_deactivate () { self::debug('deactivating');@@ -75,6 +93,11 @@ wp_unschedule_event( time(), static::schedule );
wp_clear_scheduled_hook( static::schedule ); } + /** + * main worker function: reads all bookmarks sorted by owner; + * gets them, processes them, sends the new entries + * + */ public function worker () { self::debug('worker started'); $args = array(@@ -134,12 +157,12 @@ else
$this->parse_rss( $bookmark, $owner ); } - // reschedule the worker - wp_schedule_single_event ( time() + static::revisit_time, static::schedule ); } /** + * set HTML mail filter * + * @return string HTML mime type */ public function set_html_content_type() { return 'text/html';@@ -147,15 +170,28 @@ }
/** * + * @param string $to + * @param string $link + * @param string $title + * @param string $fromname + * @param string $sourceurl + * @param string $content + * + * */ - protected function send ( $to, $link, $title, $fromname, $sourceurl, $content ) { + protected function send ( $to, $link, $title, $fromname, $sourceurl, $content, $dry = false ) { + // enable HTML mail add_filter( 'wp_mail_content_type', array( $this, 'set_html_content_type') ); + // build a more readable body $body = '<html><head></head><h1><a href="'. $link .'">'. $title .'</a></h1><body>'. $content . '<p>URL: <a href="'.$link.'">'.$link.'</a></p></body></html>'; + // this is to set the sender mail from our own domain $sitedomain = parse_url( get_bloginfo('url'), PHP_URL_HOST); + // additional header, for potential sieve backwards compatibility + // with http://www.aaronsw.com/weblog/001148 $headers = array ( 'X-RSS-ID: ' . $link, 'X-RSS-URL: ' . $link,@@ -165,22 +201,34 @@ 'From: "' . $fromname .'" <'. static::schedule . '@'. $sitedomain .'>',
); self::debug('sending ' . $title . ' to ' . $to ); - wp_mail( $to, $title, $body, $headers ); + // for debung & specific reasons, there is a dry run mode + if ( !$dry ) + $return = wp_mail( $to, $title, $body, $headers ); + + + // disable HTML mail remove_filter( 'wp_mail_content_type', array( $this, 'set_html_content_type') ); + + return $return; } /** * + * @param object $bookmark + * @param object $owner */ protected function parse_rss ( $bookmark, $owner ) { + // no bookmark, no fun if ( empty ($bookmark) || !is_object ($bookmark)) return false; + // no owner means no email, so no reason to parse if ( empty ($owner) || !is_object ($owner)) return false; + // instead of the way too simple fetch_feed, we'll use SimplePie itself if ( !class_exists('SimplePie') ) require_once( ABSPATH . WPINC . '/class-simplepie.php' );@@ -190,7 +238,7 @@
error_log('Fetching: ' . $url ); $feed = new SimplePie(); $feed->set_feed_url( $url ); - $feed->set_cache_duration ( static::revisit_time ); + $feed->set_cache_duration ( static::revisit_time - 10 ); $feed->set_cache_location( WP_CONTENT_DIR . DIRECTORY_SEPARATOR. 'cache' ); $feed->force_feed(true);@@ -207,20 +255,26 @@ $feed->handle_content_type();
if ( $feed->error() ) return new WP_Error( 'simplepie-error', $feed->error() ); + // set max items to 12 + // especially useful with first runs $maxitems = $feed->get_item_quantity( 12 ); $feed_items = $feed->get_items( 0, $maxitems ); $feed_title = $feed->get_title(); + // set the link name from the RSS title if ( !empty($feed_title) && $bookmark->link_name != $feed_title ) { global $wpdb; $wpdb->update( $wpdb->prefix . 'links', array ( 'link_name' => $feed_title ), array('link_id'=> $bookmark->link_id ) ); } + // if there's a feed author, get it, we may need it if there's no entry + // author $feed_author = $feed->get_author(); if ( $maxitems > 0 ) { $last_updated_ = 0; foreach ( $feed_items as $item ) { + // U stands for Unix Time $date = $item->get_date( 'U' ); if ( $date > $last_updated ) {@@ -231,26 +285,32 @@ $from = $from . ': ' . $author->get_name();
elseif ( $feed_author ) $from = $from . ': ' . $feed_author->get_name(); - $this->send ( + if ( $this->send ( $owner->user_email, $item->get_link(), $item->get_title(), $from, $url, $item->get_content() - ); - + )) { if ( $date > $last_updated_ ) $last_updated_ = $date; + } } } } + // poke the link's last update field, so we know what was the last sent + // entry's date $this->update_link_date ( $bookmark, $last_updated_ ); } /*** + * Microformats2 parser version + * + * @param object $bookmark + * @param object $owner * */ protected function parse_mf ( $bookmark, $owner ) {@@ -293,12 +353,13 @@ }
} } - $item = array (); - + $items = array (); foreach ($mf['items'] as $topitem ) { + // look for h-feeds if ( in_array( 'h-feed', $topitem['type'])) { if ( !empty($topitem['children'])) { foreach ( $topitem['children'] as $entry ) { + // look for h-entries if ( in_array( 'h-entry', $entry['type']) ) { $properties = $entry['properties'];@@ -323,9 +384,7 @@
$item = array ( 'url' => $url, 'content' => $content, - //'date' => $date, 'title' => $title, - //'author' => ); $items[ $time ] = $item;@@ -340,19 +399,18 @@ return false;
$last_updated_ = 0; foreach ( $items as $time => $item ) { - if ( $time > $last_updated ) { - $this->send ( + if ($this->send ( $owner->user_email, $item['url'], $item['title'], $bookmark->link_name, $item['url'], $item['content'] - ); - - if ( $time > $last_updated_ ) + )) { + if ( $time > $last_updated_ ) $last_updated_ = $time; + } } }@@ -360,7 +418,10 @@ $this->update_link_date ( $bookmark, $last_updated_ );
} /** + * in case there was an update, set the last update time for the bookmark * + * @param object $bookmark + * @param epoch $last_updated */ protected function update_link_date ( $bookmark, $last_updated ) { $current_updated = strtotime( $bookmark->link_updated );@@ -372,6 +433,11 @@ }
/** * + * debug messages; will only work if WP_DEBUG is on + * or if the level is LOG_ERR, but that will kill the process + * + * @param string $message + * @param int $level */ static function debug( $message, $level = LOG_NOTICE ) { if ( @is_array( $message ) || @is_object ( $message ) )
M
readme.txt
→
readme.txt
@@ -1,15 +1,52 @@
=== blogroll2email === Contributors: cadeyrn -Donate link: +Donate link: Tags: blogroll, links, rss, email, reader Requires at least: 3.0 -Tested up to: 4.2.1 +Tested up to: 4.2.2 Stable tag: 0.1 License: GPLv3 License URI: http://www.gnu.org/licenses/gpl-3.0.html + +Bring back the good ol' web: pull RSS, Atom and microformat feeds from your blogroll links and receive them as email. == Description == +The plugin re-activates the long forgotten [blogroll or links](https://en.support.wordpress.com/blogroll/) section of WordPress in order to turn your site to an [rss2email](http://www.aaronsw.com/weblog/001148)-like service. + += How it works: = + +* all links that has their RSS link filled in will pull the RSS feed of those sites +* those links that does not yet have RSS will be parsed as [Microformats 2](http://microformats.org/) + * in case the site has an RSS alternate link, the plugin will fill this information in and use the RSS instead of the microformats parser +* the link names will be updated based on the feed name automatically +* all the parsed entries since the last check will be sent to the link owner's email address as HTML mails with the following additional header: + * `X-RSS-ID` with the link URL + * `X-RSS-URL` with the link URL + * `X-RSS-Feed` with the feed URL + * `User-Agent` with blogroll2email, + * these are in place in order for filter script to work +* the revisit time is 30minutes ( not changeable yet ) +* the plugin uses WordPress Cron + += Credit = + +* thank you for [PHP Mf2 parser](https://github.com/indieweb/php-mf2/) from [Barnaby Walters](https://waterpigs.co.uk/) + == Installation == +1. Upload contents of `blogroll2email.zip` to the `/wp-content/plugins/` directory +2. Activate the plugin through the `Plugins` menu in WordPress + == Changelog == + +Version numbering logic: + +* every A. indicates BIG changes. +* every .B version indicates new features. +* every ..C indicates bugfixes for A.B version. + += 0.1 = +*2015-07-16* + +* first stable release