View Single Post
Old 01-09-2010, 11:59 AM   #1
rollercoaster
Zealot
rollercoaster once ate a cherry pie in a record 7 seconds.rollercoaster once ate a cherry pie in a record 7 seconds.rollercoaster once ate a cherry pie in a record 7 seconds.rollercoaster once ate a cherry pie in a record 7 seconds.rollercoaster once ate a cherry pie in a record 7 seconds.rollercoaster once ate a cherry pie in a record 7 seconds.rollercoaster once ate a cherry pie in a record 7 seconds.rollercoaster once ate a cherry pie in a record 7 seconds.rollercoaster once ate a cherry pie in a record 7 seconds.rollercoaster once ate a cherry pie in a record 7 seconds.rollercoaster once ate a cherry pie in a record 7 seconds.
 
rollercoaster's Avatar
 
Posts: 126
Karma: 1826
Join Date: Jan 2010
Device: Kindle 2
Thumbs up Google Reader Recipe hack - Download all unread insted of just starred

Hi everyone, I have been searching for a few hours and couldnt find a fix for the 'google reader shows only starred'

Finally I decided to get my hands dirty and read the Google Reader API documentation however I am new to caliber and dont know python at all but (being a .net dev) was able to make a simple modification that helped some what. here is the recipe without further ado

Google Reader: This recipe fetches from your Google Reader account unread Starred items and unread Feeds you have placed in a folder via the manage subscriptions feature.
Spoiler:

PHP Code:
import urllibremechanize
from calibre
.web.feeds.recipes import BasicNewsRecipe
from calibre import __appname__

class GoogleReader(BasicNewsRecipe):
    
title   'Google Reader'
    
description 'This recipe fetches from your Google Reader account unread Starred items and unread Feeds you have placed in a folder via the manage subscriptions feature.'
    
needs_subscription True
    __author__ 
'davec, rollercoaster, Starson17'
    
base_url 'http://www.google.com/reader/atom/'
    
oldest_article 365
    max_articles_per_feed 
50
    get_options 
'?n=%d&xt=user/-/state/com.google/read' max_articles_per_feed
    use_embedded_content 
True

    def get_browser
(self):
        
br BasicNewsRecipe.get_browser(self)
        if 
self.username is not None and self.password is not None:
            
request urllib.urlencode([('Email'self.username), ('Passwd'self.password),
                                        (
'service''reader'), ('accountType''HOSTED_OR_GOOGLE'), ('source'__appname__)])
            
response br.open('https://www.google.com/accounts/ClientLogin'request)
            
auth re.search('Auth=(\S*)'response.read()).group(1)
            
cookies mechanize.CookieJar()
            
br mechanize.build_opener(mechanize.HTTPCookieProcessor(cookies))
            
br.addheaders = [('Authorization''GoogleLogin auth='+auth)]
        return 
br

    def get_feeds
(self):
        
feeds = []
        
soup self.index_to_soup('http://www.google.com/reader/api/0/tag/list')
        for 
id in soup.findAll(Trueattrs={'name':['id']}):
            
url id.contents[0]
            
feeds.append((re.search('/([^/]*)$'url).group(1),
                          
self.base_url urllib.quote(url.encode('utf-8')) + self.get_options))
        return 
feeds 

Google Reader uber: Fetches all feeds from your Google Reader account including the uncategorized items.
Spoiler:

PHP Code:
import urllibremechanize
from calibre
.web.feeds.recipes import BasicNewsRecipe
from calibre import __appname__

class GoogleReaderUber(BasicNewsRecipe):
    
title   'Google Reader uber'
    
description 'Fetches all feeds from your Google Reader account including the uncategorized items.'
    
needs_subscription True
    __author__ 
'davec, rollercoaster, Starson17'
    
base_url 'http://www.google.com/reader/atom/'
    
oldest_article 365
    max_articles_per_feed 
250
    get_options 
'?n=%d&xt=user/-/state/com.google/read' max_articles_per_feed
    use_embedded_content 
True

    def get_browser
(self):
        
br BasicNewsRecipe.get_browser(self)
        if 
self.username is not None and self.password is not None:
            
request urllib.urlencode([('Email'self.username), ('Passwd'self.password),
                                        (
'service''reader'), ('accountType''HOSTED_OR_GOOGLE'), ('source'__appname__)])
            
response br.open('https://www.google.com/accounts/ClientLogin'request)
            
auth re.search('Auth=(\S*)'response.read()).group(1)
            
cookies mechanize.CookieJar()
            
br mechanize.build_opener(mechanize.HTTPCookieProcessor(cookies))
            
br.addheaders = [('Authorization''GoogleLogin auth='+auth)]
        return 
br

    def get_feeds
(self):
        
feeds = []
        
soup self.index_to_soup('http://www.google.com/reader/api/0/tag/list')
        for 
id in soup.findAll(Trueattrs={'name':['id']}):
            
url id.contents[0].replace('broadcast','reading-list')
            
feeds.append((re.search('/([^/]*)$'url).group(1),
                          
self.base_url urllib.quote(url.encode('utf-8')) + self.get_options))
        return 
feeds 

For a more detailed comparison see this thread. Thanks @dwanthny.

Notes:
Spoiler:

The only difference is in the max count and the line
url = id.contents[0] -->
url = id.contents[0].replace('broadcast','reading-list')

For now this seems to work by replacing the starred tag listing with the wanted 'reading-list' which is all the unread posts. Technically, 'http://www.google.com/reader/api/0/tag/list' does not return all the possible tag/state values.

I am sure other recipe super heroes here can make this better.

There is one thing though. I set the max count to 250 but it only fetched about 57, may be a limit by google as in my google reader account there were 121 items unread. (update: fixed bu adding 'oldest_article' value)

If I missed a already posted and better recipe for this please point me to it so I can benifit from it as well and dont hold back on your comments

-----------------------------------------------------------------------

Update Recipe (13/07/10): The recipe has been updated to work with the changed authentication method in Google Reader API. Thanks to Starson17.

@Kovid The name was changed from 'Google Reader Uber' to just 'Google reader' to merge the two similar recipes. The Uber verson can now be removed from the recipe set.

-----------------------------------------------------------------------
Update Recipe (14/07/10): Both recipes have been updated to work with the changed authentication method in Google Reader API. Thanks to Starson17.

.

Last edited by rollercoaster; 07-14-2010 at 11:45 PM. Reason: The recipe has been updated
rollercoaster is offline   Reply With Quote