Backup: GReader2Sqlite

Backup your google reader into a sqlite database; moreover all used xml files (received via the API) are also stored. You should use this script in an empty directory!

#!/usr/bin/perl -w

#--------Enter your credentials here-----------------
my $user= 'sjobs@gmail.com';
my $pwd = 'iPassword';



#----------------------------------------------------
use strict;
use LWP;
use XML::Simple;
use LWP::UserAgent;
use Data::Dumper;
use DBI;

my $dbh; 
my $xml;
my $st; 
my $count = 0;
my $ua = LWP::UserAgent->new;;
$ua->agent("GReader Export ");

my $req = HTTP::Request->new(GET => 'https://www.google.com/accounts/ClientLogin?service=reader&Email='.$user.'&Passwd='.$pwd);
my $res = $ua->request($req);

die $res->status_line, "\n" if (not $res->is_success);
$res->content =~ m/Auth=(\S*)/;
my $auth = $1;


$req = HTTP::Request->new(GET => 'http://www.google.com/reader/api/0/subscription/list?output=xml');
$req->header(Authorization => 'GoogleLogin auth='.$auth);
$res = $ua->request($req);
die $res->status_line, "\n" if (not $res->is_success);


open (FILEHANDLE, ">subscriptions.xml");
print FILEHANDLE $res->content;
close FILEHANDLE;

$dbh = DBI->connect("dbi:SQLite:dbname=greader.db",{AutoCommit => 0});
$dbh->do('CREATE TABLE IF NOT EXISTS subscriptions (id VARCHAR PRIMARY KEY, title VARCHAR, htmlUrl VARCHAR, file VARCHAR)');
$dbh->do('CREATE TABLE IF NOT EXISTS feeds (id VARCHAR REFERENCES subscriptions(id), title VARCHAR, link VARCHAR, label VARCHAR, content VARCHAR)');
$st = $dbh->prepare("INSERT OR REPLACE INTO subscriptions (id, title, htmlUrl, file) VALUES (?, ?, ?, ?)");

my $xs = XML::Simple->new;
$xml = $xs->XMLin($res->content, KeyAttr => {});

my $id;
my $title;
my $htmlurl;
my $label;
my $content;
my $link;
my $file;
foreach my $object (values $xml->{list}->{object}) {
	foreach my $string (values $object->{string}) {
		$id = $string->{content} if ($string->{name} eq 'id');
		$title = $string->{content} if ($string->{name} eq 'title');
		$htmlurl = $string->{content} if ($string->{name} eq 'htmlUrl');
	}
	$file = substr($htmlurl, 0, 30);
	$file =~ s/[^0-9a-z_-]+/_/gi;
	$file = $file."-".$count.".xml";
	$st->execute($id, $title, $htmlurl, $file);
	$count++;
}


$st = $dbh->prepare("SELECT id, file FROM subscriptions");
my $st_insert = $dbh->prepare("INSERT OR REPLACE INTO feeds (id, title, link, label, content) VALUES (?, ?, ?, ?, ?)");
$st->execute();
while ((my $row = $st->fetchrow_hashref())) {
	print $count--." ".$row->{id}."\n";
	$req = HTTP::Request->new(GET => 'http://www.google.com/reader/atom/'.$row->{id});
	$req->header(Authorization => 'GoogleLogin auth='.$auth);
	$res = $ua->request($req);
	next if (not $res->is_success);

	open (FILEHANDLE, ">".$row->{file});
	print FILEHANDLE $res->content;
	close FILEHANDLE;

	$xml = $xs->XMLin($res->content, KeyAttr => {});
	foreach my $entry (values $xml->{entry}) {

		open (FILEHANDLE, ">".$row->{file}.".dump");
		print FILEHANDLE Dumper($xml);
		close FILEHANDLE;

		$title = ""; $link = ""; $label = ""; $content = "";
		if (not ref($entry) eq 'HASH') {
			next;
		}
		if (ref($entry->{title}) eq 'HASH') {
			$title = $entry->{title}->{content} if (defined $entry->{title}->{content});
		} else {
			$title = $entry->{title} if (defined $entry->{title});
		}
		if(ref($entry->{link}) eq 'ARRAY'){
			$link = $entry->{link}[0]->{href} if (defined $entry->{link}[0]->{href});
		} else {
			$link = $entry->{link}->{href} if (defined $entry->{link}->{href});
		}
		if (defined $entry->{category}) {
			foreach my $l (values $entry->{category}) {
				$label = $label.$l->{label}." " if (ref($l) eq 'HASH' and defined $l->{label});
				chomp $label;
			}
		}
		if (ref($entry->{content}) eq 'HASH') {
			$content = $entry->{content}->{content} if (defined $entry->{content}->{content});
		} else {
			$content = $entry->{content} if (defined $entry->{content});
		}
		chomp $title; chomp $link; chomp $label; chomp $content;
		$st_insert->execute($row->{id}, $title, $link, $label, $content);
	}
}

Leave a comment