Tag Archives: reader

Send To Tumblr And Track With Bitly Google Reader Custom Link

Testing the “send to blogger” button…

Send To Tumblr And Track With Bitly Google Reader Custom Link: “

Google Reader just launched a “Send to Twitter” feature that allows you to share bit.ly links to interesting items in your reader with your Twitter friends.  First, awesome!

Second, Google Reader has been getting lots of product development attention lately, and with all the awesome stuff they are adding, I spend all of my time there as opposed to twitter.com/home, facebook.com/home, or Tumblr Dashboard. One thing I miss about Tumblr dashboard was easy reblogging.

How to Create Custom Send To Links in Google Reader

How to Create Custom Send To Links in Google Reader

There is a “Send to Tumblr” link as one of the defaults, but it doesn’t use bit.ly urls. So, I hacked together a custom “Send to Tumblr” link.

URL: http://tumblr.com/share?v=2&u=&t=Send To Tumblr And Track With Bitly Google Reader Custom Link&s=Send To Tumblr And Track With Bitly Google Reader Custom Link%0Avia%20kortina

Icon URL: http://assets.tumblr.com/images/favicon.gif?2

Custom Send to Tumblr with Bitly Link from Google Reader Link

Custom Send to Tumblr with Bitly Link from Google Reader Link

Possibly related posts:

  1. I Want “Read Flare” — Plugins for Sharing in Google Reader
  2. Business Cards Have Google Maps Now
  3. How To Make a Fixed Link to Twitter That’s Always Visible on Your Webpage

WordPress Plugin: Displaying your Google Reader RSS subscriptions

I’ve been meaning to write this code for a while, and I really wanted to take a stab at writing a wordpress plugin so here it goes.

The following takes in Google user credentials, and allows the user to display what RSS feeds they subscribe to on their wordpress blog

Example: The RSS that I read

Update: This plugin is now hosted by wordpress. click here


/*
Plugin Name: Google Reader Subscription List
Version: 1
Author: Timothy Broder
Description: Lists a users subscribed Google Reader feeds
*/

/*  Copyright 2009  Timothy Broder (email : timothy.broder@gmail.com)

    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
*/

if (!class_exists('GoogleReaderSubList')) {
 class GoogleReaderSubList {

  var $show_list       = 'show-google-reader-sub-list';  //the hook in a page
  var $login          = '';
  var $pass          = '';
  var $source         = 'wordpress-google-reader-sub-list-';  //the source the api sees when logging into Google
  var $service         = 'reader';
  var $login_url        = 'https://www.google.com/accounts/ServiceLoginAuth?service=mail'; //URL to login to google
  var $subscription_list_url  = 'http://www.google.com/reader/api/0/subscription/list'; //URL that holds a users subscriptions

  function GoogleReaderSubList() {
   $options    = $this->get_admin_options();
   $this->login  = $options['google_login'];
   $this->pass  = $options['google_pass'];

   $this->source = $this->source . $this->login;
  }

  function show_sub_list() {
   $stop = false;
   if ($this->login == '' || $this->login == null) {
    echo 'Google login not set';
    $stop = true;
   }
   if ($this->pass == '' || $this->pass == null) {
    echo 'Google password not set';
    $stop = true;
   }

   //check to see if the zend plugin has been installed and activated
   //http://wordpress.org/extend/plugins/zend-framework/
   if (!(defined('WP_ZEND_FRAMEWORK') && WP_ZEND_FRAMEWORK)) {
    echo 'The Zend Framework Plugin is not active.  Please install and activate it.';
    $stop = true;
   }
   if ($stop) {
    return;
   }

   $client = new Zend_Http_Client($this->login_url);

   //connect, authenticate, and handshake with Google
   $client->setCookieJar()
    ->setMethod(Zend_Http_Client::POST)
    ->setParameterPost(array(
     'continue'             => $this->subscription_list_url,
     'service'              => 'reader',
     'niu'                  => 1,
     'hl'                   => 'en',
     'Email'              => $this->login,
     'Passwd'               => $this->pass,
     'PersistentCookie'     => 'yes',
     'asts'                 => ''
    ));

   //$error_level = error_reporting();
   //error_reporting(1);
   $response = $client->request('POST');
   $client->setUri($this->subscription_list_url)->setMethod(Zend_Http_Client::GET);
   $response = $client->request()->getBody();

   if ($client->request()->getStatus() == 400) {
    ?>Unable to login with supplied Google login/password< ?
    return;
   }

   //error_reporting($error_level);

   //got the feed, parse it
   $feed = simplexml_load_string($response);

   $hashmap = array();

   //organize the feeds by tag
   foreach ($feed->list->object as $e) {
    $url = $e->string[0];
    $title = $e->string[1];
    $cat = $e->list->object->string[1];

    //make sure a feed is filed somewhere
    if ($cat == '') {
     $cat = 'unfiled';
    }
    $t = $hashmap["$cat"];

    //a category hasn't been used before
    if ($t == null) {
     $t = array($e);
     $hashmap["$cat"] = $t;
    }
    //category has been used before
    else {
     array_push($t, $e);
     $hashmap["$cat"] = $t;
    }
   }

   //sort the categories
   ksort($hashmap);

   //output
   ?>

Tags:
    < ?
    $endKey = end(array_keys($hashmap));
    foreach ($hashmap as $cat=>$t) {
     echo "$cat";
     if ($cat != $endKey) {
      echo ', ';
     }
    }
    ?>
   

< ?

   foreach ($hashmap as $cat=>$t) {
    echo "";
    echo "$cat";
    foreach ($t as $e) {
     list($feed, $url) = split('feed/', $e->string[0]);
     $title = $e->string[1];

     echo "$title";

    }
    echo '';
   }
  }

  function addContent($content) {
   // Only do this if this is a page and it has the appropriate custom field
   if (is_page()) {
    $cust_field_values = get_post_custom_values($this->show_list);
    if ($cust_field_values != NULL) {
     if (defined('WP_ZEND_FRAMEWORK') && WP_ZEND_FRAMEWORK) {
      require_once 'Zend/Loader.php';
      Zend_Loader::loadClass('Zend_Http_Client');
     }
     $content = $this->show_sub_list();
    }
   }
   return $content;
  }

  function init() {
   $this->get_admin_options();
  }  

  function get_admin_options() {
   $admin_options = array('google_login' => '',
    'google_pass' => '',
    'use_accordion' => 'true');
   $options = get_option($this->adminOptionName);
   if (!empty($options)) {
    foreach ($options as $key => $option) {
     $admin_options[$key] = $option;
    }
   }
   update_option($this->admin_optionsName, $admin_options);
   return $admin_options;
  }

  function printAdminPage() {
   $options = $this->get_admin_options();

   if (isset($_POST['update_greader_sub_list_settings'])) {
    if (isset($_POST['greader_sub_list_login'])) {
     $options['google_login'] = $_POST['greader_sub_list_login'];
    }
    if (isset($_POST['greader_sub_list_pass'])) {
     $options['google_pass'] = $_POST['greader_sub_list_pass'];
    }

    update_option($this->admin_optionsName, $options);
    echo '
' . _e('Settings Updated.', 'GoogleReaderSubList'). '


';

   }
   //$submit = _e('Update Settings', 'GoogleReaderSubList');

   echo "

                                                

                                                

                                                
                        

Google Reader gets a facelift

It’s now less “bubble” looking. I’m wondering if its pulling from my gmail theme, but I unfortunately can’t check that from work. I really like being able to hide the stats in the upper left. The only one I ever look at is how many total unread items I have.

Google I/O session videos posted with slides

As I said earlier, Quite a few presentations from Google I/O have been posted for your viewing pleasure. I’ll be glued to these this weekend while I’m on call.

Topics include
Ajax
KML
Sketchup
Android
OpenSocial
Appengine
Data APIs
Theory Talks
Youtube
Gears
Mashups
Maps
and more!

Blogger adds bloggroll

Blogger in draft added 2 new features today: a blogroll page element, and post scheduling. Post scheduling is pretty useful, you can write up your post, set the time (in the future) that you want it to post, and Blogger will do it automatically.

The second feature, a blogroll, I would like a lot more if it was done better. The main thing I like about it is that it integrates with Google Reader so if I’m linking to my friend’s blogs, I just scroll to my ‘Friends’ Tag and add them. The thing I don’t like however is that it does not support XFN or FOAF therefore not getting picked up by the SocialGraph API. For example, if I linked to my girlfriend’s blog, the blogroll just lists this as

Maybe-Not

A better link, for example from a wordpress blogroll would look something like

Maybe-Not< 

...and get picked up but the SocialGraph as having a relationship to me. Blogger is great and I love using it, but the features of wordpress are blowing it out of the water.

Google Reader stats out of Wack

First, Techcrunch came up with a list of the top blogs that users subscribe to using Google Reader. The top 3 on the list were BBC with 202,463, Google News wih 192,100, and ESPN with 189,274 . Remember, these are only the stats if the subscriber is using Google Reader, obviously there are blogs with a higher subscription count, such as the Official Google Blog (They still haven’t moved over to blogs.google.com eh?) with over 669,000 subscribers as reported by FeedBurner.

It was all well and good that Google Reader showed high stats for these blogs, but…. we were apparently duped…

In his article Google Reader Stats are BullSh*t (With Proof), Pete Cashmore goes into his explanation of the “default feed effect.” A default feed is a feed that comes already subscribed in a news aggregator , or is part of a default group (like say Digg, Engadget, and Gizmodo being in the Technology group on Google Reader). Being in these groups is a major traffic boost.

However the system has some flaws

  • There is subscription data for feeds that don’t exist
  • Google Reader does not check to see if a subscriber is active or not. (Someone signs up for Reader, adds a feed, and never touches Reader again, they count as a subscriber)
  • Feedburner pulls some stats from Google Reader
  • This problem is not limited to Google Reader. It includes many feed readers and start pages

Tune in next time after I do some research into how out wack FeedBurner statistics are.

Displaying what you read from Google Reader

I’ve been wanting to share what I subscribe to in Google Reader and using the functions I wrote I was able to do just that. Check out the article for the full run down on the unofficial Google Reader API. This is written in python but should be easily portable to php. If i get around to it, I want to make a WordPress plugin so bloggers can share what they read with their readers. This will be followed (or in parallel depending on my mood) with a Javascript version so Blogspot users can do the same in the sidebar. On to the code!

To start off we’ll just copy the functions we need from last time. Generally this is the login and SID token functions, as well as the feed list function.

from django.shortcuts import render_to_response
from django.template import Library
from elementtree import ElementTree
import urllib
import urllib2
import re

login = 'timothy.broder@gmail.com'
password = '***'
source = 'gPowered'

google_url = 'http://www.google.com'
reader_url = google_url + '/reader'
login_url = 'https://www.google.com/accounts/ClientLogin'
token_url = reader_url + '/api/0/token'
subscription_list_url = reader_url + '/api/0/subscription/list'

#login / get SED
def get_SID():
    header = {'User-agent' : source}
    post_data = urllib.urlencode({ 'Email': login, 'Passwd': password, 'service': 'reader', 'source': source, 'continue': google_url, })
    request = urllib2.Request(login_url, post_data, header)

    try :
        f = urllib2.urlopen( request )
        result = f.read()

    except:
        print 'Error logging in'

    return re.search('SID=(\S*)', result).group(1)

#get results from url
def get_results(SID, url):
    header = {'User-agent' : source}
    header['Cookie']='Name=SID;SID=%s;Domain=.google.com;Path=/;Expires=160000000000' % SID
    print url
    request = urllib2.Request(url, None, header)

    try :
        f = urllib2.urlopen( request )
        result = f.read()

    except:
        print 'Error getting data from %s' % url

    return result

#get a specific feed.  It works for any feed, subscribed or not
def get_feed(SID, url):
    return get_results(SID, get_feed_url + url.encode('utf-8'))

#get a token, this is needed for modifying to reader
def get_token(SID):
    return get_results(SID, token_url)

#get a list of the users subscribed feeds
def get_subscription_list(SID):
    return get_results(SID, subscription_list_url)

Then we’ll want to get rid off all the information in the feed that we don’t want and load what we do into a data dictionary. After its in the dictionary, feed names and links (and the folders they are in) are ready to be displayed. As usual, I use Django to display my pages, but everything is the same up to the final return in the Feeds method. Below is an example of what each subscription looks like in the Google Reader Feed, and below that is how to process it


feed/http://www.ubuntu.com/rss.xml Ubuntu  user/16162999404522159936/label/dev dev   1186137757794 
class myFeed:
    def __init__(self, name, link):
        self.name = name
        self.link = link

def Feeds(request):
    SID = get_SID()
    feeds = get_subscription_list(SID)
    tree = ElementTree.fromstring(feeds)
    d = dict()   

    #loop through each feed
    for object in tree.findall('list')[0].findall('object'):
        strings = object.findall('string')
        key = object.findall('list')[0].findall('object')[0].findall('string')[1].text

        #tag already exists, add to the list
        try:
            d[key].append(myFeed(strings[1].text, strings[0].text.replace('feed/', '')))
        #tag doesn't exist, create list
        except KeyError:
            d[key] = [myFeed(strings[1].text, strings[0].text.replace('feed/', ''))]

    return render_to_response('pages/feeds.html', {
    'feeds': d,
    })

For those of you that use django or are just curious how I end up displaying the feeds, this is what i have in my view:


My Reading


  • {% for item in feeds.items %}
  • {{ item.0 }}



{% endfor %}

Again, too see what I subscribe to, click here

Google Reader adds Search Box!!

Finally!! No more using Yahoo Pipes to search the feeds!

I’m sitting here waiting for my friend Eli to pick me up from his apartment for a nice lunch over at dreamworks, glancing over a few feeds (I have a LOT to catch up on when I get back to NY), and one jumped out at me, the Google Reader Team has finally added a search box to Google reader.

This box will search all of your feeds! Also included in this release are:

- Ability to hide side navigation (I just tried it, it’s very well done)
- Unread count is now 1,000+ rather then 100+ (this is going to be good for me when I get back)
- Forward and Back buttons now have more responsiveness when moving between folders and feeds

Check out Google Blog Search for more blog searching.

Performance Optimization WordPress Plugins by W3 EDGE