Tuesday, June 2, 2009

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/passwordlist->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: $t) { echo "$cat"; if ($cat != $endKey) { echo ', '; } } ?>

$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 Subscription List

Google Login

Google Password

"; } } } if (class_exists('GoogleReaderSubList')) { $greader_sub_list = new GoogleReaderSubList(); } if (!function_exists('greader_sub_list_ap')) { function greader_sub_list_ap() { global $greader_sub_list; if (!isset($greader_sub_list)) { return; } if (function_exists('add_options_page')) { add_options_page('gReader Subscriptions', 'gReader Subscriptions', 9, basename(__FILE__), array(&$greader_sub_list, 'printAdminPage')); } } } if (isset($greader_sub_list)) { add_action('admin_menu', 'greader_sub_list_ap'); add_action('activate_google-raeder-list/google-reader-list.php', array(&$greader_sub_list, 'init')); add_filter('the_content', array(&$greader_sub_list, 'addContent'), '7'); }

Quick Google Authentication in PHP

Here is a quick way to authenticate against Google and retrieve a protected feed. It does not use the supported ClientLogin method but it does allow you to get to some unsupported feeds (Reader, Bookmarks, etc) The Zend Gdata library is required

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

 
$client = new Zend_Http_Client($login_url);

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


$response = $client->request('POST');
$client->setUri($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

Thursday, May 28, 2009

Diggnation NYC, June 4th!

- Link

Veeeeery excited about this.  Last year was a blast
When?
Thursday, June 4th, 2009
7:30pm
Where?
Webster Hall
125 East 11th Street, New York City, NY
view map
Streaming?
No
Live Event?
Yes
Venue Website:

Thursday, April 30, 2009

Google Maps F-Bombs street names!

Good stuff. Link

Tuesday, April 28, 2009

How a Programmer reads your resume

- Link

Friday, April 17, 2009

How to manage podcasts in Winamp (screw itunes)

So I really have been digging the Windows 7 beta.  However, Itunes does not sync podcasts correctly on the 64 bit version.  IF syncing works at all, it takes a while. I had used winamp to listen to my music a while ago, but had switched to amarok when I started single booting linux (yes, I hated Vista that much).  Now that I'm back to using windows a bit, I wanted my podcast experience to go flawlessly.

As much as I dislike iTunes, they have got podcast management down pat

  • search for podcast
  • subscribe to podcast
  • download episodes
  • sync with ipod
  • after an episode has been listened to, delete from computer hard drive
That last point is the most important part, everything else can be done manually

All this can be done with winamp. You will need two things, winamp and the ml_iPod plugin.  While winamp does come with ipod support built in, ml_iPod has many more features.  The following steps should get you up to speed on podcasting with winamp
  • install winamp
  • install the ml_iPod plugin (it will tell you it has to remove the built in ipod plugin, this is ok)
  • set a directory to save the episodes in



  • plug in your ipod
  • enable podcast support for the ipod
  • point it to your episode folder
  • set the query for when to delete old episodes



  • Add your podcasts by searching for them in the directory, or adding them manually using their RSS feed



After this you should be good to go. podcasts!

Wednesday, April 8, 2009

Big Appengine news: Cron, Java, Firewalled Data, DB Import

- Link

Java Support: This was the first, and most popular request in the bug tracker. Followed closely by PHP support.  Google has merged the simplicity of appengine with the robustness of java, and added it to their Eclipse plugin to boot.

Cron Support: The cron support works by calling a URL at a given interval. I'm not sure if cron jobs are also restricted by the timeout policy, hopefully they will be allowed to be longer.

Secure Data Connector: An exampled of this would be accessing data behind a corporate firewall.  Might be a (good/bad) idea ;)

Bulk Uploader: Dump data into appengine from another database or a CSV file