GR2WP – Google reader shared items till WordPress

I kategorin Tips så delar jag med mig av intressanta inlägg som jag hittat via mina RSS-flöden i Google Reader.

Det finns flera andra som har liknande funktion på sina bloggar, de använder då exempelvis FeedWordPress, SharedItems2WP eller WP-o-Matic. Av olika anledningar passade ingen av dessa lösningar mig perfekt, mest för att jag ville ha full kontroll över flödet och för att det var så länge sen jag programmerade i perl …

Som jag nyss avslöjade, så skrev jag alltså ett perl-script som hämtar min shared items-feed från google reader (via XML::Atom::Syndication::Feed) och sen trycker jag in en post med de senaste bloggtipsen i WordPress (via XMLRPC::Lite).

Effekten blir den här.

Gå till Google reader, hitta ett intressant inlägg och välj ”Share with note”.

Share with note i google reader
Share with note i google reader

Lägg till en anteckning och spara.

Kör sen perlscriptet gr2wp.pl (Google Reader To WordPress).
Då skapas ett WP-inlägg med alla nya utdelade bloggposter.

Resultatet i WordPress
Resultatet i WordPress

Alla ”Jonas tipsar”-inlägg

Här kommer perlscriptet. Du får gärna använda och modifiera det helt fritt. Jag har utgått från ett script som postade google-reader shared items till delicious.

#!/usr/bin/perl -w

use strict;
use LWP::Simple;
use XML::Atom::Syndication::Feed;
use XMLRPC::Lite;
use XML::XPath;
use WordPress::XMLRPC;
use HTML::Entities;
use Time::Local;

######## CONFIGURATION ########
my $debug = 0;
# Your Google Shared Items Feed URL
my $feed_url = 'yourgoogleshareditemsfeedurl';

# A local file location for the feed
my $feed_file = '/path/to/localfeedfile.xml';

# Timestamp file
my $ts_file = "/path/to/gr2wp_timestamp.lis";

# WordPress post title
$wp_title = "post title";

# WordPress post categories (example: ['Fashion','Beauty'])
# (The categories must exist before posting)
@wp_categories = ['category'];

# WordPress user
$wp_user = 'username';

# WordPress password
$wp_pwd = 'password';

# WordPress proxy (URL to xmlrpc.php, don't forget to activate xmlrpc protocol in blog!)
$wp_proxy = 'http://sitename/xmlrpc.php';

######## END CONFIGURATION ########

# start time handling
my @now = localtime;
my $time = timelocal(@now);

# Subtract one week (default if no timestamp file found)
my $default_start = $time - 7 * 24 * 60 * 60; 

my $start_date;

# fetch last startdate or, if not found, pick a date one week ago
if (-e $ts_file) {
	open FP, "<$ts_file" or die "Could not open file $ts_file: $! \n";
	$start_date = ()[0];
	close FP;
	chomp $start_date;
	$start_date =~ s/\s//g;
} else {
	$start_date = $default_start;
}

print "Start date: ", $start_date, "\n" if $debug;
print "now: ", $time, "\n" if $debug;

# Set the google reader namespace URI
my $gr = 'http://www.google.com/schemas/reader/atom/';

#snag a local copy of the shared items feed
my $status = getstore($feed_url,$feed_file);
	die "Error $status fetching the Google Reader feed." unless is_success($status); 

# Init the wordpress API
my $o = WordPress::XMLRPC->new({
username => $wp_user,
password => $wp_pwd,
proxy => $wp_proxy,
});

#parse the shared items feed
my $feed = XML::Atom::Syndication::Feed->new($feed_file);
my @entries = $feed->entries;

# loop through items in the feed
my $buf = "
    "; my $post_count = 0; foreach my $entry (@entries) { # grab the title, link, and source title my $postTitle = encode_entities($entry->title->body); my $postLink = $entry->link->href; my $sourceTitle = encode_entities($entry->source->title->body); # get the time this item was shared my $shareTime = $entry->get_attribute($gr,'crawl-timestamp-msec'); # convert from milliseconds to seconds $shareTime = $shareTime/1000; # skip item if it was shared before the start date next if $shareTime < $start_date; $post_count++; #grab any notes my $xp = $entry->as_xml; # get the notes, this should probably be simplified ... my $notes = encode_entities($1, "\200-\377") if $xp =~ m/annotation>(.*?)<\/content>/; # Remove the "CDATA" bit, if present $notes = $1 if $notes =~ m//s; print "Title: $postTitle\n" if $debug; print "Link: $postLink\n" if $debug; print "Source: $sourceTitle\n" if $debug; # Create the post content $buf .= "
  • $sourceTitle: $postTitle
  • "; if ($notes) { $buf .= "
    "; $buf .= "$notes"; $buf .= "
    "; } } $buf .= "
"; #Delete the local copy of the feed unlink($feed_file); # timestamp my $ymd = sub{sprintf '%04d-%02d-%02d', $_[5]+1900, $_[4]+1, $_[3]}->(localtime); my $content_hashref; $content_hashref->{title} = "$wp_title - $ymd"; $content_hashref->{categories} = @wp_categories; $content_hashref->{description} = $buf; # Post to wordpress if ($post_count > 0) { $o->newPost($content_hashref, 1); open FP, ">$ts_file" or die "Could not open file $ts_file for writing: $!\n"; print FP $time; close FP; } else { print "No posts\n"; } # Debugging purposes, write post to local file gr2wp_debug.lis if ($debug) { open OFP, ">gr2wp_debug.lis"; print OFP $buf; close OFP; }

För enkelhetens skull kör jag perl-scriptet en gång om dagen, via crontab.