Mike Steder avatar Mike Steder committed d53299f

Added g-client.

Comments (0)

Files changed (24)

 ;(load "menu.el")
 (load "remote.el")
 
+; g-client
+;(load "msg.el")
 ;; Reminders:
 ; don't forget you can get an elisp repl: M-x ielm
 

emacs.d/g-client/.excludes

+g-client.tar.bz2
+.svn

emacs.d/g-client/COPYING

+                                                                                                                                                                                                           Copyright (C) 2007 Google Inc.                                                                                                                                                                             
+                                                                                                                                                                                                            
+ 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 Street, Fifth Floor, Boston, MA  02110-1301, USA.                                                                                                                            
+  

emacs.d/g-client/Makefile

+# $Id: Makefile 4373 2007-02-17 03:59:51Z tv.raman.tv $
+# $Author: tv.raman.tv $
+# Description:  Makefile for g-client -- An Emacs client for Google services
+# Keywords: Emacs, G-CLIENT, Makefile
+# {{{ LCD Entry:
+
+# LCD Archive Entry:
+# g-client| T. V. Raman |raman@cs.cornell.edu
+# An emacs  interface to Google services |
+# $Date: 2007-02-16 19:59:51 -0800 (Fri, 16 Feb 2007) $ |
+#  $Revision: 4373 $ |
+# Location undetermined
+#
+
+# }}}
+# {{{ Copyright:
+
+#Copyright (C) 2006--2007, T. V. Raman
+# This file is not part of GNU Emacs, but the same permissions apply.
+#
+# GNU Emacs 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, or (at your option)
+# any later version.
+#
+# GNU Emacs 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 GNU Emacs; see the file COPYING.  If not, write to
+# the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+
+# }}}
+# {{{make definitions
+
+# what emacs is called on your system
+EMACS = emacs
+# How to run in batch mode
+BATCH = -batch -q -no-site-file
+DEPS= -l ./g-load-path.el -l ./g-loaddefs.el
+COMPILE =  -f batch-byte-compile
+# How to compile
+%.elc:  %.el
+	$(EMACS) $(BATCH)  $(DEPS)  $(COMPILE) $<
+
+OBJECTS= g-auth.elc \
+g-utils.elc \
+g.elc \
+gblogger.elc \
+gcal.elc \
+greader.elc
+
+# }}}
+# {{{  User level targets all
+
+all: $(OBJECTS)
+
+# }}}
+# {{{build time target: config
+
+config: g-loaddefs.el g-cus-load.el
+
+
+force:
+
+g-cus-loads.el: force
+g-loaddefs.el: force
+
+.phony: g-cus-loads.el
+.phony: g-loaddefs.el
+
+g-loaddefs.el:
+	echo ";;;Auto generated" > g-loaddefs.el
+	$(EMACS) $(BATCH) -l ./g-autogen.el -f g-autogen-generate-autoloads
+
+g-cus-load.el:
+	$(EMACS) $(BATCH) -l ./g-autogen.el -f g-autogen-custom-make-dependencies "."
+
+# }}}
+# {{{  Make rules for the various modules
+g-utils.elc: g-utils.el g-loaddefs.el
+g.elc: g.el g-loaddefs.el
+g-auth.elc: g-auth.el g-utils.elc
+greader.elc: greader.el g-auth.elc
+gcal.elc: gcal.el g-auth.elc
+gblogger.elc: gblogger.el g-auth.elc
+
+# }}}
+# {{{dist
+
+dist:g-client.tar.bz2
+
+g-client.tar.bz2: ${SOURCES}
+	rm -f $@
+	tar  cfj $@ -X .excludes -C ..  g-client
+
+# }}}
+# {{{  user level target-- clean
+
+clean:
+	rm -f *.elc   g-cus-loads.el g-loaddefs.el
+
+# }}}
+# {{{ end of file
+
+#local variables:
+#major-mode: makefile-mode
+#eval:  (fold-set-marks "# {{{" "# }}}")
+#fill-column: 90
+#folded-file: t
+#end:
+
+# }}}

emacs.d/g-client/atom-view.xsl

+<?xml version="1.0"?>
+<!--
+Author: T. V. Raman <raman@cs.cornell.edu>
+License: GPL
+View an Atom feed as clean HTML
+-->
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+                xmlns:atom="http://purl.org/atom/ns#"
+                xmlns:w3a="http://www.w3.org/2005/Atom"
+                xmlns:xhtml="http://www.w3.org/1999/xhtml"
+                xmlns:gr="http://www.google.com/schemas/reader/atom/"
+                version="1.0">
+  <xsl:output encoding="iso8859-15" method="html" indent="yes"/>
+  
+  <xsl:template match="atom:feed|w3a:feed">
+    <html>
+      <head>
+        <title>
+          <xsl:apply-templates select="atom:title|w3a:title"/>
+        </title>
+      </head>
+      <body>
+        <h1><xsl:value-of select="atom:title|w3a:title"
+        disable-output-escaping="yes"/>
+        </h1>
+        <table>
+          <tr>
+            <xsl:for-each select="atom:link|w3a:link">
+              <td><xsl:apply-templates select="."/></td>
+            </xsl:for-each>
+          </tr>
+        </table>
+        <h2>Table Of Contents</h2>
+        <ol>
+          <xsl:apply-templates select="atom:entry|w3a:entry" mode="toc"/>
+        </ol>
+        <xsl:apply-templates select="atom:entry|w3a:entry"/>
+        <h2>
+          <xsl:value-of select="title"/>
+        </h2>
+
+        <p>
+          <xsl:apply-templates select="atom:tagline|w3a:tagline"/>
+          <xsl:apply-templates select="atom:author|w3a:author"/>
+        </p>
+      </body>
+    </html>
+  </xsl:template>
+  
+  <xsl:template match="atom:entry|w3a:entry">
+    <h2>
+      <a>
+        <xsl:attribute name="name">
+          <xsl:value-of select="generate-id(.)"/> 
+        </xsl:attribute>
+        <xsl:attribute name="id"> <xsl:value-of select="generate-id(.)"/>
+        </xsl:attribute>
+        <xsl:apply-templates select="atom:title|w3a:title"/>
+      </a>
+    </h2>
+    
+    <TABLE>
+      <tr>
+        <xsl:for-each select="atom:link|w3a:link">
+          <td><xsl:apply-templates select="."/></td>
+        </xsl:for-each>
+      </tr>
+    </TABLE>
+    <xsl:apply-templates select="atom:summary|atom:content|w3a:content|w3a:summary"/>
+    <p>
+      <xsl:apply-templates
+          select="atom:link[@rel='alternate']|w3a:link[@rel='alternate']"/>
+      <em><xsl:value-of  select="atom:author/atom:name"
+      disable-output-escaping="yes"/>
+      <xsl:if test="atom:published|w3a:published">
+        <xsl:text> at </xsl:text>
+      </xsl:if>
+      <xsl:value-of select="atom:published|w3a:published"/></em>
+    </p>
+  </xsl:template>
+  <xsl:template match="atom:entry|w3a:entry" mode="toc">
+    <li>
+      <a>
+        <xsl:attribute name="href">
+          #<xsl:value-of select="generate-id(.)"/> 
+        </xsl:attribute>
+        <xsl:value-of select="atom:title|w3a:title"
+                      disable-output-escaping="yes"/>
+      </a>
+    </li>
+  </xsl:template>
+  <xsl:template
+      match="atom:content|atom:summary|w3a:content|w3a:summary">
+    <xsl:choose>
+      <xsl:when test="@type='application/xhtml+xml'">
+        <xsl:copy-of select="node()"/>
+      </xsl:when>
+      <xsl:when test="@type='html' or @type='text/html'">
+        <xsl:value-of disable-output-escaping="yes"
+                      select="node()"/>
+      </xsl:when>
+      <!-- for legacy atom 0.3-->
+      <xsl:when test="@mode='escaped'">
+        <xsl:value-of disable-output-escaping="yes"
+                      select="node()"/>
+      </xsl:when>
+    </xsl:choose>
+  </xsl:template>
+  <xsl:template match="xhtml:div">
+    <xsl:copy/>
+  </xsl:template>
+  <xsl:template match="atom:link|w3a:link">
+    <a>
+      <xsl:attribute name="href">
+        <xsl:value-of
+            select="@href"/>
+      </xsl:attribute>
+      <xsl:choose>
+        <xsl:when test="@rel='service.edit'">[Edit]</xsl:when>
+        <xsl:when test="@rel='edit'">[Edit]</xsl:when>
+        <xsl:when test="@rel='service.post'">[Post]</xsl:when>
+        <xsl:when test="@rel='next'">[Next]</xsl:when>
+        <xsl:when test="@rel='self'">[Bookmark]</xsl:when>
+        <xsl:when test="@rel='alternate'">[Alternate]</xsl:when>
+        <xsl:otherwise>[<xsl:value-of select="substring-after(@rel,'#')"/>]</xsl:otherwise>
+      </xsl:choose>
+    </a>
+  </xsl:template>
+  
+  
+  
+</xsl:stylesheet>

emacs.d/g-client/blogger-edit-post.xsl

+<?xml version="1.0"?>
+<!--$Id:$-->
+<!--
+Author: T. V. Raman
+License: GPL
+Description: Used by gblogger to edit out server-generated elements 
+when posting or updating an entry.
+-->
+
+<xsl:stylesheet xmlns:atom="http://www.w3.org/2005/Atom" xmlns="http://www.w3.org/2005/Atom" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
+  <xsl:output method="xml" indent="yes"/>
+<xsl:template match="atom:id|atom:issued|atom:modified|atom:created|atom:published|atom:updated"/>  
+<xsl:template match="atom:content">
+  <content type="xhtml">
+    <xsl:attribute name="type">xhtml</xsl:attribute>
+<xsl:apply-templates/>
+  </content>
+</xsl:template>
+  <xsl:template match="*|@*">
+    <xsl:copy>
+      <xsl:apply-templates select="@*"/>
+      <xsl:apply-templates select="node()"/>
+    </xsl:copy>
+  </xsl:template>
+</xsl:stylesheet>

emacs.d/g-client/g-auth.el

+;;; g-auth.el --- Google Authentication Module
+;;;$Id: g-auth.el,v 1.6 2006/10/23 16:51:50 raman Exp $
+;;; $Author: raman $
+;;; Description:  Google Authentication Module
+;;; Keywords: Google   Auth
+;;{{{  LCD Archive entry:
+
+;;; LCD Archive Entry:
+;;; g-client| T. V. Raman |raman@cs.cornell.edu
+;;; An emacs interface to Google services|
+;;; $Date: 2006/10/23 16:51:50 $ |
+;;;  $Revision: 1.6 $ |
+;;; Location undetermined
+;;; License: GPL
+;;;
+
+;;}}}
+;;{{{ Copyright:
+
+;;; Copyright (c) 2006 and later, Google Inc.
+;;; All rights reserved.
+
+;;; Redistribution and use in source and binary forms, with or without modification,
+;;; are permitted provided that the following conditions are met:
+
+;;;     * Redistributions of source code must retain the above copyright notice,
+;;;       this list of conditions and the following disclaimer.
+;;;     * Redistributions in binary form must reproduce the above copyright notice,
+;;;       this list of conditions and the following disclaimer in the documentation
+;;;       and/or other materials provided with the distribution.
+;;;     * The name of the author may not be used to endorse or promote products
+;;;       derived from this software without specific prior written permission.
+
+;;; THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+;;; AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+;;; IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+;;; ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+;;; LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+;;; CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+;;; GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+;;; HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+;;; STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
+;;; WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+;;; SUCH DAMAGE.
+
+;;}}}
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;; Commentary:
+;;{{{  introduction
+
+;;; Google Auth using Curl
+;;; Implements an authentication component for use in Google
+;;; Clients -- see http://code.google.com/apis/accounts/AuthForInstalledApps.html
+
+;;; Steps:
+;;; 0) Connect via https to
+;;; https://www.google.com/accounts/ClientLogin?service=%s
+;;; where %s is the service name e.g. reader, blogger etc.
+;;; and pass in the email/passwd as POST data.
+;;; 1) Obtain the response, and cache the auth token
+;;; 2) Cache this token for use during its lifetime.
+
+;;; defstruct g-auth encapsulates this functionality.
+;;; See module greader.el for sample usage
+
+;;}}}
+;;{{{  Required modules
+
+(require 'cl)
+(declaim  (optimize  (safety 0) (speed 3)))
+(require 'g-utils)
+
+;;}}}
+;;{{{ Customizations:
+
+(defgroup g-auth nil
+  "Google Authentication"
+  :group 'g)
+(defcustom g-user-email nil
+  "Google account  address."
+  :type '(choice
+          (const :tag "none" nil)
+          (string :tag "username@gmail.com" ""))
+  :group 'g)
+
+(defcustom g-auth-lifetime '(0 1800 0)
+  "Lifetime of authentication token as a list suitable for
+`current-time'."
+  :type 'sexp
+  :group 'g-auth)
+
+;;}}}
+;;{{{ Generators :
+
+(defvar g-auth-scratch-buffer" *g auth*"
+  "Scratch buffer we do authentication work.")
+
+(defvar g-auth-url-pattern
+  "https://www.google.com/accounts/ClientLogin?service=%s"
+  "URL to login to Google services.")
+
+(defsubst g-auth-url (service)
+  "Return auth URL  for specified service."
+  (declare (special g-auth-url-pattern))
+  (format g-auth-url-pattern
+          (g-url-encode service)))
+
+;;}}}
+;;{{{ G Auth Data Structures:
+
+;;; email and password are supplied by user.
+;;; Auth, sid and lsid are obtained from the server.
+
+(defstruct g-auth
+  (username  (user-login-name))
+  email
+  password
+  token
+  session-id ;gsession-id
+  cookie-alist
+  service
+  (lifetime  g-auth-lifetime)
+  timestamp
+  post-auth-action)
+
+(defsubst g-cookie (name auth-handle)
+  "Return cookie for `name' from auth-handle if present."
+  (let ((pair (assoc name
+                     (g-auth-cookie-alist auth-handle))))
+    (when pair (cdr pair))))
+
+(defconst g-authorization-header-format
+  "--header 'Authorization: GoogleLogin auth=%s'  \
+--header 'Content-Type: application/atom+xml' "
+  "HTTP headers to send.")
+
+(defsubst g-authorization (auth-handle)
+  "Return authorization header."
+  (declare (special g-authorization-header-format))
+  (format g-authorization-header-format
+              (g-cookie "Auth" auth-handle)))
+
+(defsubst g-auth-expired-p (auth-handle)
+  "Check if  token for specified service has expired."
+  (cond
+   ((and (null (g-auth-token auth-handle))
+         (null (g-auth-cookie-alist auth-handle)))t)
+   ((time-less-p (g-auth-lifetime auth-handle)
+                 (time-since (g-auth-timestamp auth-handle)))
+    t)
+   (t nil)))
+
+;;}}}
+;;{{{ G Authenticate
+
+(defun g-authenticate (auth-handle)
+  "Authenticate    using credentials in auth-handle.
+Populate auth-handle with the returned cookies and token."
+  (declare (special g-auth-scratch-buffer g-curl-program
+                    g-user-email))
+  (let* ((post-auth-action (g-auth-post-auth-action auth-handle))
+        (email (or (g-auth-email auth-handle)
+                   g-user-email
+                   (read-from-minibuffer "User Address: ")))
+        (password
+         (or (g-auth-password auth-handle)
+             (read-passwd
+              (format "Password for %s:"
+                      email))))
+        (buff (get-buffer-create g-auth-scratch-buffer))
+        (fields nil))
+    (setf (g-auth-email auth-handle) email
+          (g-auth-password auth-handle) password
+          (g-auth-cookie-alist auth-handle) nil)
+    (save-excursion
+      (set-buffer buff)
+      (erase-buffer)
+      (insert
+       (format "Email=%s&Passwd=%s&source=g-emacs&accountType=hosted_or_google"
+               (g-url-encode email)
+               (g-url-encode password)))
+      (shell-command-on-region
+       (point-min) (point-max)
+       (format "%s %s -X POST --data-binary @- %s 2>/dev/null"
+               g-curl-program g-cookie-options
+               (g-auth-url (g-auth-service auth-handle)))
+       (current-buffer)
+       'replace)
+      (goto-char (point-min))
+      (while (not (eobp))
+        (skip-syntax-forward " ")
+        (setq fields (split-string
+                      (buffer-substring (line-beginning-position)
+                                        (line-end-position))
+                      "="))
+        (push (cons (first fields) (second fields))
+              (g-auth-cookie-alist auth-handle))
+        (forward-line 1))
+      (when (and post-auth-action
+                 (fboundp post-auth-action))
+        (funcall post-auth-action auth-handle))
+      (setf (g-auth-timestamp auth-handle) (current-time))
+      auth-handle)))
+
+(defun g-auth-ensure-token (auth-handle)
+  "Ensure token is  still valid, re-authenticating if necessary."
+  (when (g-auth-expired-p auth-handle)
+    (g-authenticate auth-handle))
+  auth-handle)
+
+;;}}}
+(provide 'g-auth)
+;;{{{ end of file
+
+;;; local variables:
+;;; folded-file: t
+;;; byte-compile-dynamic: t
+;;; end:
+
+;;}}}

emacs.d/g-client/g-autogen.el

+;;; g-autogen.el --- Generate autoloads for G
+;;; $Id: g-autogen.el,v 1.4 2006/08/18 22:06:58 raman Exp $
+;;; $Author: raman $
+;;; Description:  autoload Wizard for the G client
+;;; Keywords: Google Services
+;;{{{  LCD Archive entry:
+
+;;; LCD Archive Entry:
+;;; g-client| T. V. Raman |raman@cs.cornell.edu
+;;; An emacs interface to Google Services|
+;;; $Date: 2006/08/18 22:06:58 $ |
+;;;  $Revision: 1.4 $ |
+;;; Location undetermined
+;;; License: GPL
+;;;
+
+;;}}}
+;;{{{ Copyright:
+
+;;; Copyright (c) 2006 and later, Google Inc.
+;;; All rights reserved.
+
+;;; Redistribution and use in source and binary forms, with or without modification,
+;;; are permitted provided that the following conditions are met:
+
+;;;     * Redistributions of source code must retain the above copyright notice,
+;;;       this list of conditions and the following disclaimer.
+;;;     * Redistributions in binary form must reproduce the above copyright notice,
+;;;       this list of conditions and the following disclaimer in the documentation
+;;;       and/or other materials provided with the distribution.
+;;;     * The name of the author may not be used to endorse or promote products
+;;;       derived from this software without specific prior written permission.
+
+;;; THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+;;; AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+;;; IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+;;; ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+;;; LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+;;; CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+;;; GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+;;; HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+;;; STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
+;;; WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+;;; SUCH DAMAGE.
+
+;;}}}
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+;;{{{ Introduction:
+
+;;; Generate autoloads from autoload cookies
+
+;;}}}
+;;{{{  Required modules
+
+(require 'cl)
+(declaim  (optimize  (safety 0) (speed 3)))
+(require 'autoload)
+(load-library "cus-dep")
+
+;;}}}
+;;{{{ Variables
+
+(defvar g-directory (and load-file-name
+                         (file-name-directory load-file-name))
+  "Directory where Google Client is installed.")
+
+(defvar g-autogen-autoloads-file
+  (expand-file-name "g-loaddefs.el" g-directory)
+  "File that holds automatically generated autoloads for G.")
+
+;;}}}
+;;{{{ generate autoloadms
+
+(defvar g-autogen-updator
+  (cond
+   ((fboundp 'update-autoloads-from-directories)
+    'update-autoloads-from-directories)
+   ((fboundp  'update-directory-autoloads)
+    'update-directory-autoloads))
+  "Function used to extract autoloads.")
+
+(defun g-autogen-generate-autoloads ()
+  "Generate G autoloads."
+  (declare (special  g-autogen-autoloads-file
+                     g-autogen-updator g-directory))
+  (let ((generated-autoload-file g-autogen-autoloads-file))
+    (funcall g-autogen-updator g-directory)))
+
+;;}}}
+;;{{{  generate custom autoloads:
+
+(defvar g-autogen-custom-dependencies-file
+  (expand-file-name "g-cus-load.el" g-directory)
+  "File that holds custom dependency information.")
+
+(defun g-autogen-custom-make-dependencies ()
+  "Generate G custom dependencies."
+  (declare (special  g-autogen-custom-dependencies-file))
+  (let ((generated-custom-dependencies-file g-autogen-custom-dependencies-file))
+    (custom-make-dependencies)))
+
+;;}}}
+(provide 'g-autogen)
+;;{{{ end of file
+
+;;; local variables:
+;;; folded-file: t
+;;; byte-compile-dynamic: nil
+;;; end:
+
+;;}}}

emacs.d/g-client/g-client.html

+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
+               "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml"
+lang="en" xml:lang="en">
+<head>
+<title>An Emacs Client For Google Services</title>
+<meta http-equiv="Content-Type" content="text/html;charset=iso-8859-1"/>
+<meta name="generator" content="Org-mode"/>
+<meta name="generated" content="2007/03/02 07:03:45 AM"/>
+<meta name="author" content="T.V Raman"/>
+<style type="text/css">
+  html {
+	font-family: Times, serif;
+	font-size: 12pt;
+  }
+  .title { text-align: center; }
+  .todo  { color: red; }
+  .done { color: green; }
+  .timestamp { color: grey }
+  .timestamp-kwd { color: CadetBlue }
+  .tag { background-color:lightblue; font-weight:normal }
+  .target { background-color: lavender; }
+  pre {
+	border: 1pt solid #AEBDCC;
+	background-color: #F3F5F7;
+	padding: 5pt;
+	font-family: courier, monospace;
+  }
+  table { border-collapse: collapse; }
+  td, th {
+	vertical-align: top;
+	border: 1pt solid #ADB9CC;
+  }
+</style>
+</head><body>
+<h1 class="title">An Emacs Client For Google Services</h1>
+
+<h2>1 An Emacs Interface To Google Services</h2>
+
+
+<p>
+Google offers a number of services using  a Google
+account. Many of these services also expose a Web API. this
+package provides a set of Emacs modules for accessing these
+services from inside Emacs. These modules are designed with an
+Emacs-centric, rather than a Web-browser centered view of the
+world. Where necessary Emacs package <code>browse-url</code> is used to
+invoke the Web browser of choice.
+</p>
+<p>
+Note that this is still  work in progress. I'm releasing it as
+part of the Emacspeak project since I believe the package already
+has sufficiently useful functionality for users who spend a large
+amount of their time inside Emacs. There is no dependency on
+Emacspeak, and all clients provided here can be used
+without Emacspeak loaded.
+</p>
+
+<h3>1.1 Installation</h3>
+
+
+<p>
+These are needed only if installing package <code>g-client</code>
+stand-alone, i.e. outside of Emacspeak.
+</p>
+<ul>
+<li>
+Unpack the tar archive and place the resulting <code>g-client</code>
+directory on your emacs <code>load-path</code>.
+</li>
+<li>
+Type <code>make</code> to compile the code.
+</li>
+<li>
+In your .emacs, add <code>(load-library "g")</code> to set it up.
+
+</li>
+</ul>
+<h3>1.2 How It Works</h3>
+
+
+<p>
+Clients are implemented using Google APIs based on Atom
+Publishing Protocol <a href="http://bitworking.org/projects/atom/draft-ietf-atompub-protocol-09.html">APP</a> and Google Data APIs (<a href="http://code.google.com/apis/gdata/index.html">GData</a>). We use <code>curl</code>
+to retrieve content via <i>HTTPS</i> and <code>xsltproc</code> to transform the
+retrieved content to browsable HTML.
+</p>
+<p>
+Clients sign you in the first time you invoke commands that require
+authentication. Once signed in, the session cookie is cached for future
+use. Session cookies presently expire in 30 minutes, and clients check for
+expired cookies when authentication is needed. If the cookie has expired,
+clients retrieve a fresh cookie using the authentication credentials provided
+earlier. Note that authorization tokens etc are specific to a
+given service.
+</p>
+
+<h3>1.3 Top-level Customizations</h3>
+
+
+<p>
+All clients in this package use Emacs' <code>customize</code> interface to
+set user preferences.
+The most commonly used  ones are enumerated below.
+</p>
+<ul>
+<li>
+<code>g-user-email</code> Default email-id to use. Individual clients
+typically override this via user option
+<code>&lt;clientname&gt;-user-email</code>.
+</li>
+<li>
+<code>g-html-handler</code> Name of function that handles HTML content.
+
+</li>
+</ul>
+<h3>1.4 Google Blogger <i>gblogger</i></h3>
+
+
+<p>
+This client implements posting, editting and deleting of blog
+entries using the new Blogger API --- it replaces the now
+obsolete <a href="http://emacsgeek.blogspot.com/2006/01/announcing-atom-blogger.html">atom-blogger</a> that implemented similar functionality
+using the old Blogger API. It uses value of customization option
+<code>g-user-email</code> by default; this can be overridden via option
+<code>gblogger-user-email</code>. See <a href="http://code.google.com/apis/blogger/overview.html">Blogger GData API</a> for the underlying
+APIs used. For editing posts, I recommend installing <a href="http://www.thaiopensource.com/nxml-mode/">nxml-mode</a>.
+</p>
+<ul>
+<li>
+<i>Browse</i> Command <code>gblogger-blog</code> brings up the list of blogs
+owned by the currently authenticated user.
+</li>
+<li>
+<i>Posting</i> Command <code>gblogger-new-entry</code> takes a <b>post URL</b> and sets
+up a special buffer where you can compose your
+article. the <b>post url</b> is obtained from the feed of blogs
+above, use the <b>post</b> link for the blog to which you wish to
+post.
+</li>
+<li>
+<i>Browsing</i>      Command <code>gblogger-atom-display</code> displays the
+atom feed for a specified blog as a browsable HTML page. In
+addition to reading your blog, this helps you find the <b>edit     url</b> for individual posts.
+</li>
+<li>
+<i>Editting</i> Command <code>gblogger-edit-entry</code> takes the <b>edit url</b>
+of a previously posted entry. It retrieves the entry, and
+sets up a special composition buffer where you can edit the entry.
+</li>
+<li>
+<i>Submitting</i> The special composition buffer created by
+commands <code>gblogger-new-entry</code> and <code>gblogger-edit-entry</code>
+provide a special command <code>gblogger-publish</code> (bound to <code>C-c     C-c</code>) that submits the entry to blogger.
+</li>
+<li>
+<i>Deleting</i> Command <code>gblogger-delete-entry</code> deletes an entry
+specified by its <b>edit url</b>.
+
+</li>
+</ul>
+<h3>1.5 Google Calendar <i>gcal</i></h3>
+
+
+<p>
+This client can be used to view, add or delete events from the
+Google Calendar for the authenticated user. It uses value of
+customization option <code>g-user-email</code> by default; this can be
+overridden via option <code>gcal-user-email</code>. Commands that display
+calendar items optionally accept the feed url of the calendar to
+view; this can be used to view calendars to which the
+authenticated user has read access. See <a href="http://code.google.com/apis/calendar/overview.html">GData Calendar API</a> for
+the underlying APIs used.
+</p>
+<ul>
+<li>
+<i>View</i> Command <code>gcal-calendar-agenda</code> displays the default
+calendar for the authenticated user. A prefix arg prompts for
+the calendar to display. This command is best used from
+inside the Emacs calendar; in this case, it uses the date
+under point when showing the agenda.
+</li>
+<li>
+<i>Add</i> Command <code>gcal-add-event</code> prompts for event details and
+adds it to the calendar.
+</li>
+<li>
+<i>Accept</i> Command <code>gcal-accept-event</code> accepts an event. Event
+is specified using the <b>edit url</b> of the event.
+</li>
+<li>
+<i>Delete</i> Command <code>gcal-delete-event</code> deletes an event. Event
+is specified using the <b>edit url</b> of the event.
+
+</li>
+</ul>
+<h3>1.6 Google Reader <i>greader</i></h3>
+
+
+<p>
+This client allows the authenticated user to read, browse and
+subscribe/unsubscribe to feeds.
+It uses value of customization option <code>g-user-email</code> by
+default; this can be overridden via option <code>g-user-email</code>.
+</p>
+<ul>
+<li>
+<i>Reading</i> Command <code>greader-reading-list</code> displays the
+reading list (river of news).
+</li>
+<li>
+<i>Browsing</i> Command <code>greader-feed-list</code> displays a
+browsable Web page with pointers to  subscribed feeds.
+</li>
+<li>
+<i>Finding</i> Command <code>greader-find-feeds</code> searches for matching
+feeds to subscribe.
+</li>
+<li>
+<i>Subscribing</i> Commands <code>greader-subscribe-feed</code> and
+<code>greader-unsubscribe-feed</code> are used to subscribe and
+unsubscribe.
+</li>
+<li>
+<i>Labeling</i> Command <code>greader-star</code> and <code>greader-add-label</code> are
+used to label articles.
+</li>
+<li>
+<i>Reading</i> Starred  articles can be read by
+providing a prefix argument to command
+<code>greader-reading-list</code>. Thus, C-u M-x greader-reading-list
+will prompt for the specific set of articles to retrieve.
+
+</li>
+</ul>
+<p class="author"> Author: T.V Raman
+<a href="mailto:raman@cs.cornell.edu>">&lt;raman@cs.cornell.edu>&gt;</a>
+</p>
+<p class="date"> Date: 2007/03/02 07:03:45 AM</p>
+</body>
+</html>

emacs.d/g-client/g-client.org

+* An Emacs Interface To Google Services
+
+Google offers a number of services using  a Google
+account. Many of these services also expose a Web API. this
+package provides a set of Emacs modules for accessing these
+services from inside Emacs. These modules are designed with an
+Emacs-centric, rather than a Web-browser centered view of the
+world. Where necessary Emacs package =browse-url= is used to
+invoke the Web browser of choice.
+
+Note that this is still  work in progress. I'm releasing it as
+part of the Emacspeak project since I believe the package already
+has sufficiently useful functionality for users who spend a large
+amount of their time inside Emacs. There is no dependency on
+Emacspeak, and all clients provided here can be used
+without Emacspeak loaded.
+
+** Installation
+
+These are needed only if installing package =g-client=
+stand-alone, i.e. outside of Emacspeak.
+
+  - Unpack the tar archive and place the resulting =g-client=
+    directory on your emacs =load-path=.
+  - Type =make= to compile the code.
+  - In your .emacs, add =(load-library "g")= to set it up.
+
+** How It Works
+
+Clients are implemented using Google APIs based on Atom
+Publishing Protocol [[http://bitworking.org/projects/atom/draft-ietf-atompub-protocol-09.html][APP]] and Google Data APIs ([[http://code.google.com/apis/gdata/index.html][GData]]). We use =curl=
+to retrieve content via /HTTPS/ and =xsltproc= to transform the
+retrieved content to browsable HTML.
+
+Clients sign you in the first time you invoke commands that require
+authentication. Once signed in, the session cookie is cached for future
+use. Session cookies presently expire in 30 minutes, and clients check for
+expired cookies when authentication is needed. If the cookie has expired,
+clients retrieve a fresh cookie using the authentication credentials provided
+earlier. Note that authorization tokens etc are specific to a
+given service.
+
+** Top-level Customizations
+
+All clients in this package use Emacs' =customize= interface to
+set user preferences.
+The most commonly used  ones are enumerated below.
+
+  - =g-user-email= Default email-id to use. Individual clients
+    typically override this via user option
+    =<clientname>-user-email=.
+  - =g-html-handler= Name of function that handles HTML content.
+
+** Google Blogger /gblogger/
+
+This client implements posting, editting and deleting of blog
+entries using the new Blogger API --- it replaces the now
+obsolete [[http://emacsgeek.blogspot.com/2006/01/announcing-atom-blogger.html][atom-blogger]] that implemented similar functionality
+using the old Blogger API. It uses value of customization option
+=g-user-email= by default; this can be overridden via option
+=gblogger-user-email=. See [[http://code.google.com/apis/blogger/overview.html][Blogger GData API]] for the underlying
+APIs used. For editing posts, I recommend installing [[http://www.thaiopensource.com/nxml-mode/][nxml-mode]].
+
+  - /Browse/ Command =gblogger-blog= brings up the list of blogs
+    owned by the currently authenticated user.
+  - /Posting/ Command =gblogger-new-entry= takes a *post URL* and sets
+    up a special buffer where you can compose your
+    article. the *post url* is obtained from the feed of blogs
+    above, use the *post* link for the blog to which you wish to
+    post.
+  - /Browsing/      Command =gblogger-atom-display= displays the
+    atom feed for a specified blog as a browsable HTML page. In
+    addition to reading your blog, this helps you find the *edit
+    url* for individual posts.
+  - /Editting/ Command =gblogger-edit-entry= takes the *edit url*
+    of a previously posted entry. It retrieves the entry, and
+    sets up a special composition buffer where you can edit the entry.
+  - /Submitting/ The special composition buffer created by
+    commands =gblogger-new-entry= and =gblogger-edit-entry=
+    provide a special command =gblogger-publish= (bound to =C-c
+    C-c=) that submits the entry to blogger.
+  - /Deleting/ Command =gblogger-delete-entry= deletes an entry
+    specified by its *edit url*.
+
+** Google Calendar /gcal/
+
+This client can be used to view, add or delete events from the
+Google Calendar for the authenticated user. It uses value of
+customization option =g-user-email= by default; this can be
+overridden via option =gcal-user-email=. Commands that display
+calendar items optionally accept the feed url of the calendar to
+view; this can be used to view calendars to which the
+authenticated user has read access. See [[http://code.google.com/apis/calendar/overview.html][GData Calendar API]] for
+the underlying APIs used.
+
+  - /View/ Command =gcal-calendar-agenda= displays the default
+    calendar for the authenticated user. A prefix arg prompts for
+    the calendar to display. This command is best used from
+    inside the Emacs calendar; in this case, it uses the date
+    under point when showing the agenda.
+  - /Add/ Command =gcal-add-event= prompts for event details and
+    adds it to the calendar.
+  - /Accept/ Command =gcal-accept-event= accepts an event. Event
+    is specified using the *edit url* of the event.
+  - /Delete/ Command =gcal-delete-event= deletes an event. Event
+    is specified using the *edit url* of the event.
+
+** Google Reader /greader/
+
+This client allows the authenticated user to read, browse and
+subscribe/unsubscribe to feeds.
+It uses value of customization option =g-user-email= by
+default; this can be overridden via option =g-user-email=.
+
+  - /Reading/ Command =greader-reading-list= displays the
+    reading list (river of news).
+  - /Browsing/ Command =greader-feed-list= displays a
+    browsable Web page with pointers to  subscribed feeds.
+  - /Finding/ Command =greader-find-feeds= searches for matching
+    feeds to subscribe.
+  - /Subscribing/ Commands =greader-subscribe-feed= and
+    =greader-unsubscribe-feed= are used to subscribe and
+    unsubscribe.
+  - /Labeling/ Command =greader-star= and =greader-add-label= are
+    used to label articles.
+  - /Reading/ Starred  articles can be read by
+    providing a prefix argument to command
+    =greader-reading-list=. Thus, C-u M-x greader-reading-list
+    will prompt for the specific set of articles to retrieve.
+
+#+TITLE:     An Emacs Client For Google Services
+#+AUTHOR:    T.V Raman
+#+EMAIL:     raman@cs.cornell.edu>
+#+LANGUAGE:  en
+#+OPTIONS:   H:3 num:t toc:nil \n:nil @:t ::t |:t ^:t *:t TeX:t LaTeX:nil

emacs.d/g-client/g-cus-load.el

+;;; g-cus-load.el --- automatically extracted custom dependencies
+;;
+;;; Code:
+
+(put 'atom-blogger 'custom-loads '("gblogger"))
+(put 'greader 'custom-loads '(greader))
+(put 'applications 'custom-loads '(g))
+(put 'g-auth 'custom-loads '(g-auth))
+(put 'gcal 'custom-loads '(gcal))
+(put 'gblogger 'custom-loads '("gblogger"))
+(put 'g 'custom-loads '(g-utils g-auth "gblogger" gcal greader))
+;; These are for handling :version.  We need to have a minimum of
+;; information so `customize-changed-options' could do its job.
+
+;; For groups we set `custom-version', `group-documentation' and
+;; `custom-tag' (which are shown in the customize buffer), so we
+;; don't have to load the file containing the group.
+
+;; `custom-versions-load-alist' is an alist that has as car a version
+;; number and as elts the files that have variables or faces that
+;; contain that version. These files should be loaded before showing
+;; the customization buffer that `customize-changed-options'
+;; generates.
+
+;; This macro is used so we don't modify the information about
+;; variables and groups if it's already set. (We don't know when
+;; g-cus-load.el is going to be loaded and at that time some of the
+;; files might be loaded and some others might not).
+(defmacro custom-put-if-not (symbol propname value)
+  `(unless (get ,symbol ,propname)
+     (put ,symbol ,propname ,value)))
+
+
+(defvar custom-versions-load-alist nil
+ "For internal use by custom.")
+
+(provide 'g-cus-load)
+;; Local Variables:
+;; version-control: never
+;; no-byte-compile: t
+;; no-update-autoloads: t
+;; coding: utf-8
+;; End:
+;;; g-cus-load.el ends here

emacs.d/g-client/g-load-path.el

+;;; g-load-path.el -- Setup Emacs load-path for compiling grep
+;;; $Id: g-load-path.el 4158 2006-08-31 03:16:54Z tv.raman.tv $
+;;; $Author: tv.raman.tv $
+;;; Description:  Sets up load-path for g-client compilation
+;;; Keywords: g-client, Google services  for Emacs
+;;{{{  LCD Archive entry:
+;;; LCD Archive Entry:
+;;; g-client| T. V. Raman |raman@cs.cornell.edu
+;;; An Emacs client for Google services
+;;; $Date: 2006-08-30 20:16:54 -0700 (Wed, 30 Aug 2006) $ |
+;;;  $Revision$ |
+;;; Location undetermined
+;;;
+
+;;}}}
+;;{{{  Copyright:
+;;;Copyright (C) 2006--2007, T. V. Raman
+;;;
+;;; This file is not part of GNU Emacs, but the same permissions apply.
+;;;
+;;; GNU Emacs 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, or (at your option)
+;;; any later version.
+;;;
+;;; GNU Emacs 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 GNU Emacs; see the file COPYING.  If not, write to
+;;; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+
+;;}}}
+(defvar g-directory
+  (and load-file-name
+       (file-name-directory load-file-name))
+  "Directory where g-client  is built. ")
+
+(unless (member g-directory load-path )
+  (setq load-path
+        (cons g-directory load-path )))
+
+(setq byte-compile-warnings
+      '(redefine callargs free-vars
+                 unresolved obsolete))
+
+(provide 'g-load-path)

emacs.d/g-client/g-loaddefs.el

+;;;Auto generated
+
+;;;### (autoloads (gcal-emacs-calendar-setup gcal-show-event gcal-show-calendar
+;;;;;;  gcal-delete-event gcal-add-event gcal-read-event) "gcal"
+;;;;;;  "gcal.el" (17895 27547))
+;;; Generated autoloads from gcal.el
+
+(autoload 'gcal-read-event "gcal" "\
+Prompt user for event params and return an event structure.
+
+\(fn TITLE CONTENT WHERE START END WHO TRANSPARENCY STATUS)" t nil)
+
+(autoload 'gcal-add-event "gcal" "\
+Add a calendar event.
+
+\(fn)" t nil)
+
+(autoload 'gcal-delete-event "gcal" "\
+Delete a calendar event.
+
+\(fn EVENT-URI)" t nil)
+
+(autoload 'gcal-show-calendar "gcal" "\
+Show calendar for currently authenticated user.
+
+\(fn &optional CALENDAR START-MIN START-MAX)" t nil)
+
+(autoload 'gcal-show-event "gcal" "\
+Show event at URL.
+
+\(fn URL)" t nil)
+
+(define-prefix-command 'gcal-calendar-prefix-map)
+
+(autoload 'gcal-emacs-calendar-setup "gcal" "\
+Setup GCal keybindings in Emacs calendar.
+
+\(fn)" nil nil)
+
+;;;***
+
+;;;### (autoloads (greader-find-feeds greader-star greader-add-label
+;;;;;;  greader-untag-feed greader-tag-feed greader-title-feed greader-unsubscribe-feed
+;;;;;;  greader-subscribe-feed greader-feed-list greader-preferences
+;;;;;;  greader-reading-list) "greader" "greader.el" (17895 4046))
+;;; Generated autoloads from greader.el
+
+(autoload 'greader-reading-list "greader" "\
+Ensure our cookies are live, and get the reading list.
+Optional interactive prefix `state' prompts for state to retrieve
+
+e.g., starred.
+
+\(fn &optional STATE)" t nil)
+
+(autoload 'greader-preferences "greader" "\
+Ensure our cookies are live, and get all preferences for this
+user.
+
+\(fn)" t nil)
+
+(autoload 'greader-feed-list "greader" "\
+Retrieve list of subscribed feeds.
+Optional interactive prefix arg `sort' sorts feeds based on newly
+arrived articles.
+
+\(fn &optional SORT)" t nil)
+
+(autoload 'greader-subscribe-feed "greader" "\
+Subscribe to specified feed.
+
+\(fn FEED-URL)" t nil)
+
+(autoload 'greader-unsubscribe-feed "greader" "\
+UnSubscribe from specified feed.
+
+\(fn FEED-URL)" t nil)
+
+(autoload 'greader-title-feed "greader" "\
+Title  specified feed.
+
+\(fn FEED-URL)" t nil)
+
+(autoload 'greader-tag-feed "greader" "\
+Tag  specified feed.
+
+\(fn FEED-URL)" t nil)
+
+(autoload 'greader-untag-feed "greader" "\
+Remove Tag from specified feed.
+
+\(fn FEED-URL)" t nil)
+
+(autoload 'greader-add-label "greader" "\
+Add label to this item.
+
+\(fn ITEM-URL LABEL)" t nil)
+
+(autoload 'greader-star "greader" "\
+Star this item.
+
+\(fn ITEM-URL)" t nil)
+
+(autoload 'greader-find-feeds "greader" "\
+Find feeds matching query.
+
+\(fn QUERY)" t nil)
+
+;;;***
+
+;;;### (autoloads nil nil ("g-auth.el" "g-autogen.el" "g-load-path.el"
+;;;;;;  "g-utils.el" "g.el" "json.el") (19389 57186 673460))
+
+;;;***
+
+;;;### (autoloads (gblogger-publish gblogger-put-entry gblogger-post-entry
+;;;;;;  gblogger-new-entry gblogger-edit-entry gblogger-atom-display
+;;;;;;  gblogger-blog) "gblogger" "gblogger.el" (17895 4046))
+;;; Generated autoloads from gblogger.el
+
+(autoload 'gblogger-blog "gblogger" "\
+Retrieve and display feed of feeds after authenticating.
+
+\(fn)" t nil)
+
+(autoload 'gblogger-atom-display "gblogger" "\
+Retrieve and display specified feed after authenticating.
+
+\(fn URL)" t nil)
+
+(autoload 'gblogger-edit-entry "gblogger" "\
+Retrieve entry and prepare it for editting.
+The retrieved entry is placed in a buffer ready for editing.
+`url' is the URL of the entry.
+
+\(fn URL)" t nil)
+
+(autoload 'gblogger-new-entry "gblogger" "\
+Create a new Blog post.
+
+\(fn URL)" t nil)
+
+(autoload 'gblogger-post-entry "gblogger" "\
+Post buffer contents  as  updated entry.
+
+\(fn)" t nil)
+
+(autoload 'gblogger-put-entry "gblogger" "\
+PUT buffer contents as new entry.
+
+\(fn)" t nil)
+
+(autoload 'gblogger-publish "gblogger" "\
+Publish current entry.
+
+\(fn)" t nil)
+
+;;;***

emacs.d/g-client/g-utils.el

+;;; g-utils.el --- Google Client Utilities
+;;;$Id: g-utils.el,v 1.14 2006/10/13 01:38:19 raman Exp $
+;;; $Author: raman $
+;;; Description:  Google Client utilities
+;;; Keywords: Google   Atom API, Google Services
+;;{{{  LCD Archive entry:
+
+;;; LCD Archive Entry:
+;;; g-client| T. V. Raman |raman@cs.cornell.edu
+;;; An emacs interface to Google Services|
+;;; $Date: 2006/10/13 01:38:19 $ |
+;;;  $Revision: 1.14 $ |
+;;; Location undetermined
+;;; License: GPL
+;;;
+
+;;}}}
+;;{{{ Copyright:
+
+;;; Copyright (c) 2006 and later, Google Inc.
+;;; All rights reserved.
+
+;;; Redistribution and use in source and binary forms, with or without modification,
+;;; are permitted provided that the following conditions are met:
+
+;;;     * Redistributions of source code must retain the above copyright notice,
+;;;       this list of conditions and the following disclaimer.
+;;;     * Redistributions in binary form must reproduce the above copyright notice,
+;;;       this list of conditions and the following disclaimer in the documentation
+;;;       and/or other materials provided with the distribution.
+;;;     * The name of the author may not be used to endorse or promote products
+;;;       derived from this software without specific prior written permission.
+
+;;; THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+;;; AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+;;; IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+;;; ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+;;; LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+;;; CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+;;; GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+;;; HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+;;; STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
+;;; WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+;;; SUCH DAMAGE.
+
+;;}}}
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;; Commentary:
+;;{{{  introduction
+
+;;; Common Code  e.g. helper functions.
+;;; Used by modules like greader, gblogger etc.
+
+;;}}}
+;;{{{  Required modules
+
+(require 'cl)
+(require 'backquote)
+(require 'json)
+(declaim  (optimize  (safety 0) (speed 3)))
+
+;;}}}
+;;{{{ Customizations:
+
+(defvar g-directory (and load-file-name
+                                  (file-name-directory load-file-name))
+  "Directory where Google Client is installed.")
+
+(defvar g-scratch-buffer" *g scratch*"
+"Scratch buffer we do authentication work.")
+
+(defcustom g-curl-program "curl"
+  "Name of CURL executable."
+  :type 'string
+  :group 'g)
+
+(defcustom g-atom-view-xsl
+  (expand-file-name "atom-view.xsl" g-directory)
+  "XSLT transform to convert Atom feed to HTML."
+  :type 'string
+  :group 'g)
+
+(defcustom g-atom-edit-filter
+  (expand-file-name "blogger-edit-post.xsl" g-directory)
+  "XSLT transform used to tidy up an entry before posting.
+For now, this is blogger specific."
+  :type 'string
+  :group 'g)
+
+(defcustom g-curl-common-options
+  "--compressed --silent --location --location-trusted"
+  "Common options to pass to all Curl invocations."
+  :type 'string
+  :group 'g)
+
+(defcustom g-html-handler 'browse-url-of-buffer
+  "Function that processes HTML.
+Receives buffer containing HTML as its argument."
+  :type '(choice
+          (function-item browse-url-of-buffer)
+          (function-item switch-to-buffer)
+
+          (function :format "%t %v" :tag "Custom:"))
+  :group 'g)
+
+(defcustom g-url-under-point 'browse-url-url-at-point
+  "Function used to get URL from current context."
+  :type '(choice
+          (function-item browse-url-url-at-point)
+          (function-item w3-view-this-url)
+          (function :format "%t %v" :tag "Custom:"))
+  :group 'g)
+
+(defcustom g-xslt-program "xsltproc"
+  "XSLT Processor."
+  :type 'string
+  :group 'g)
+
+(defcustom g-cookie-jar
+   (expand-file-name "~/.g-cookie-jar")
+   "Cookie jar used for Google services.
+Customize this to live on your local disk."
+   :type 'file
+   :set '(lambda (sym val)
+          (declare (special g-cookie-options))
+          (setq g-cookie-options
+                 (format "--cookie %s --cookie-jar %s"
+                                 val val))
+          (set-default sym val))
+   :group 'g)
+
+(defvar g-cookie-options
+ (format "--cookie %s --cookie-jar %s"
+                                 g-cookie-jar g-cookie-jar)
+ "Options to pass for using our cookie jar.")
+
+(defcustom g-curl-debug nil
+  "Set to T to see Curl stderr output."
+  :type 'boolean
+  :group 'g)
+
+(defcustom g-xslt-debug nil
+  "Set to T to see xsltproc  stderr output."
+  :type 'boolean
+  :group 'g)
+
+;;}}}
+;;{{{ debug helpers
+
+(defsubst g-curl-debug ()
+  "Determines if we show stderr output."
+  (declare (special g-curl-debug))
+  (if g-curl-debug
+" 2>/dev/null"
+""))
+
+(defsubst g-xslt-debug ()
+  "Determines if we show stderr output."
+  (declare (special g-xslt-debug))
+  (if g-xslt-debug
+" 2>/dev/null"
+""))
+
+;;}}}
+;;{{{ url encode:
+
+(defsubst g-url-encode (str)
+  "URL encode  string."
+  (mapconcat '(lambda (c)
+		(cond ((= c 32) "+")
+		      ((or (and (>= c ?a) (<= c ?z))
+			   (and (>= c ?A) (<= c ?Z))
+			   (and (>= c ?0) (<= c ?9)))
+		       (char-to-string c))
+		      (t (upcase (format "%%%02x" c)))))
+	     str
+	     ""))
+
+;;}}}
+;;{{{ transform region
+
+(defsubst g-xsl-transform-region (start end xsl)
+  "Replace region by result of transforming via XSL."
+  (declare (special g-xslt-program))
+  (shell-command-on-region
+   start end
+   (format "%s %s - %s"
+           g-xslt-program xsl (g-xslt-debug))
+   'replace))
+
+;;}}}
+;;{{{ html unescape
+
+(defvar g-html-charent-alist
+  '(("&lt;" . "<")
+    ("&gt;" . ">")
+    ("&quot;" . "\"")
+    ("&apos;" . "'") ("&amp;" . "&"))
+  "Alist of HTML character entities to unescape.")
+
+(defsubst g-html-unescape-region (start end)
+  "Unescape HTML entities."
+  (declare (special g-html-charent-alist))
+  (save-excursion
+    (loop for entry in g-html-charent-alist
+          do
+          (let ((entity (car  entry))
+                (replacement (cdr entry )))
+            (goto-char start)
+            (while (search-forward entity end t)
+              (replace-match replacement ))))))
+
+(defsubst g-html-escape-region (start end)
+  "Escape HTML entities."
+  (declare (special g-html-charent-alist))
+  (save-excursion
+    (loop for entry in g-html-charent-alist
+          do
+          (let ((entity (cdr  entry))
+                (replacement (car entry )))
+            (goto-char start)
+            (while (search-forward entity end t)
+              (replace-match replacement ))))))
+
+;;}}}
+;;{{{ json conveniences:
+
+(defsubst g-json-get (key object)
+  "Return object.key from json object or nil if not found."
+  (cdr (assoc key object)))
+
+(defalias 'g-json-aref 'aref)
+
+;;}}}
+;;{{{ helper macros
+
+(defmacro g-using-scratch(&rest body)
+  "Evaluate forms in a  ready to use temporary buffer."
+  `(progn
+     (declare (special g-scratch-buffer))
+  (let ((buffer (get-buffer-create g-scratch-buffer))
+        (buffer-undo-list t))
+    (save-excursion
+      (set-buffer  buffer)
+      (kill-all-local-variables)
+      (erase-buffer)
+      (progn ,@body)))))
+
+(defsubst g-get-result (command)
+  "Run command and return its output."
+  (g-using-scratch
+      (shell-command command (current-buffer) 'replace)
+      (buffer-string)))
+
+(defsubst g-json-get-result(command)
+  "Get command results and return json object read from result
+string."
+  (json-read-from-string
+   (g-get-result command)))
+
+(defsubst g-display-result (command style)
+  "Display result retrieved by command using specified style.
+Typically, content is pulled using Curl , converted to HTML using style  and
+  previewed via `g-html-handler'."
+  (declare (special g-xslt-program g-html-handler))
+  (g-using-scratch
+      (shell-command command (current-buffer))
+      (when style
+        (g-xsl-transform-region (point-min) (point-max) style))
+      (funcall g-html-handler (current-buffer))))
+
+(defsubst g-display-xml-string (string style)
+  "Display XML string  using specified style.
+XML string is transformed via style
+  and previewed via `g-html-handler'."
+  (declare (special g-xslt-program g-html-handler))
+  (g-using-scratch
+   (insert string )
+   (when style
+     (g-xsl-transform-region (point-min) (point-max) style))
+   (funcall g-html-handler (current-buffer))))
+
+;;}}}
+;;{{{  HTTP Headers:
+
+(defvar g-crlf-pair
+  (format "%c%c"  10  10)
+  "HTTP headers are ended by a CRLF pair.
+Note that in the Curl output, we see lf rather than crlf.")
+
+(defsubst g-http-headers (start end)
+  "Parse HTTP headers in region and return an alist."
+  (declare (special g-crlf-pair))
+  (goto-char start)
+  (when (search-forward g-crlf-pair end 'no-error )
+    (setq end (point)))
+  (save-restriction
+    (narrow-to-region start end)
+    (let ((headers nil)
+          (pos nil)
+          (fields nil))    (goto-char (point-min))
+          (when (looking-at "HTTP/[0-9.]+")
+            (skip-syntax-forward "^ ")
+            (skip-syntax-forward " ")
+            (setq pos (point))
+            (skip-syntax-forward "^ ")
+            (push
+             (cons "Status"
+                   (buffer-substring-no-properties
+                    pos (point)))
+             headers)
+            (forward-line 1))
+          (while (not (eobp))
+            (setq fields
+                  (split-string (buffer-substring-no-properties
+                                 (line-beginning-position)
+                                 (line-end-position))
+                                ": "))
+            (when (= 2 (length fields))
+              (push
+               (cons (first fields) (second fields))
+               headers))
+            (forward-line 1))
+          headers)))
+
+(defsubst g-http-body (start end)
+  "Return body from HTTP response."
+  (declare (special g-crlf-pair))
+  (goto-char start)
+  (cond
+   ((search-forward g-crlf-pair end 'no-error )
+    (buffer-substring-no-properties (point) end))
+   (t "")))
+
+(defsubst g-http-header (name header-alist)
+  "Return specified header from headers-alist."
+    (when (assoc name header-alist) (cdr (assoc name header-alist))))
+
+;;}}}
+(provide 'g-utils)
+;;{{{ end of file
+
+;;; local variables:
+;;; folded-file: t
+;;; byte-compile-dynamic: t
+;;; end:
+
+;;}}}

emacs.d/g-client/g.el

+;;; g.el --- Google Client
+;;;$Id: g.el,v 1.10 2006/08/18 22:01:42 raman Exp $
+;;; $Author: raman $
+;;; Description:  Google Client
+;;; Keywords: emacs g-client, Google   Atom API, Google Services
+;;{{{  LCD Archive entry:
+
+;;; LCD Archive Entry:
+;;; g-client| T. V. Raman |raman@cs.cornell.edu
+;;; An emacs interface to Google Services|
+;;; $Date: 2006/08/18 22:01:42 $ |
+;;;  $Revision: 1.10 $ |
+;;; Location undetermined
+;;; License: GPL
+;;;
+
+;;}}}
+;;{{{ Copyright:
+
+;;; Copyright (c) 2006 and later, Google Inc.
+;;; All rights reserved.
+
+;;; Redistribution and use in source and binary forms, with or without modification,
+;;; are permitted provided that the following conditions are met:
+
+;;;     * Redistributions of source code must retain the above copyright notice,
+;;;       this list of conditions and the following disclaimer.
+;;;     * Redistributions in binary form must reproduce the above copyright notice,
+;;;       this list of conditions and the following disclaimer in the documentation
+;;;       and/or other materials provided with the distribution.
+;;;     * The name of the author may not be used to endorse or promote products
+;;;       derived from this software without specific prior written permission.
+
+;;; THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+;;; AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+;;; IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+;;; ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+;;; LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+;;; CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+;;; GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+;;; HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+;;; STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
+;;; WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+;;; SUCH DAMAGE.
+
+;;}}}
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;; Commentary:
+;;{{{  introduction
+
+;;; Top-level bootstrap module for Google Client.
+;;; Loads in authentication module and sets up per-service
+;;modules:
+;;; Google Reader: greader
+;;; Google Calendar: gcal
+;;; ...
+
+;;}}}
+;;{{{ customizations:
+
+(defgroup g nil
+  "Google Client"
+  :group 'applications)
+
+;;}}}
+;;{{{ Variables :
+
+;;}}}
+;;{{{ pull in autoloads
+
+(load-library "g-loaddefs")
+(load-library "g-cus-load")
+(add-hook 'calendar-mode-hook
+          'gcal-emacs-calendar-setup)
+
+;;}}}
+(provide 'g)
+;;{{{ end of file
+
+;;; local variables:
+;;; folded-file: t
+;;; byte-compile-dynamic: t
+;;; end:
+
+;;}}}

emacs.d/g-client/gblogger.el

+;;; gblogger.el ---  new Atom Blogger API client
+;;; $Id:$
+;;; $Author:$
+;;; Description:  ATOM Blogger API
+;;; Keywords: g-client, Blogger Atom API
+;;{{{  LCD Archive entry:
+
+;;; LCD Archive Entry:
+;;; g-client| T. V. Raman |raman@cs.cornell.edu
+;;; An emacs interface to Google services|
+;;; $Date: 2006-09-28 09:37:06 -0700 (Thu, 28 Sep 2006) $ |
+;;;  $Revision$ |
+;;; Location undetermined
+;;; License: GPL
+;;;
+
+;;}}}
+;;{{{ Copyright:
+
+;;; Copyright (c) 2005--2006, Google Inc.
+;;; All rights reserved.
+
+;;; Redistribution and use in source and binary forms, with or without modification,
+;;; are permitted provided that the following conditions are met:
+
+;;;     * Redistributions of source code must retain the above copyright notice,
+;;;       this list of conditions and the following disclaimer.
+;;;     * Redistributions in binary form must reproduce the above copyright notice,
+;;;       this list of conditions and the following disclaimer in the documentation
+;;;       and/or other materials provided with the distribution.
+;;;     * The name of the author may not be used to endorse or promote products
+;;;       derived from this software without specific prior written permission.
+
+;;; THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+;;; AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+;;; IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+;;; ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+;;; LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+;;; CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+;;; GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+;;; HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+;;; STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
+;;; WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+;;; SUCH DAMAGE.
+
+;;}}}
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;; Commentary:
+;;{{{  introduction
+
+;;; Simple wrapper using Curl to post/edit Blogger.com Blogs
+;;; posts are edited as XML
+;;;nxml-mode is highly recommend and will be used if available.
+
+;;;Usage:
+;;; gblogger-blog -- Show feed of current user's blogs
+;;; gblogger-new-entry -- Create a new post
+;;; gblogger-edit-entry -- Edit previously posted entry
+;;; gblogger-delete-entry -- Delete previously posted entry
+
+
+
+
+
+;;; Commands prompt for the URI of the entry being manipulated ---
+;;; this is the service.edit URI.
+;;; You can customize things via custom.
+
+;;}}}
+;;{{{  Required modules
+
+(require 'cl)
+(require 'derived)
+(require 'g-utils)
+(require 'g-auth)
+
+;;}}}
+;;{{{ customizations
+
+(defgroup gblogger nil
+  "Emacs client for posting to blogger."
+  :group 'g)
+
+(defcustom gblogger-user-email nil
+  "Mail address that identifies blogger user."
+  :type '(choice
+          (const :tag "none" nil)
+          (string :tag "username@gmail.com" ""))
+  :group 'gblogger)
+
+(defcustom gblogger-user-password nil
+  "Password for authenticating to reader account."
+  :type '(radio (const :tag "Prompt for password" nil)
+                (string :tag "Save password in .emacs"))
+  :group 'gblogger)
+
+(defcustom gblogger-author (user-full-name)
+  "Author name under which we post."
+  :type 'string
+  :group 'atom-blogger)
+
+(defvar gblogger-generator-name "http://purl.org/net/emacs-gblogger/"
+  "Name of this generator.")
+
+(defvar gblogger-publish-action nil
+  "This is set up by the various interactive comands to trigger
+  the appropriate action when one is ready to publish.")
+
+(defvar gblogger-new-entry-template
+  "<entry xmlns='http://www.w3.org/2005/Atom'>
+  <generator url=\"%s\">%s</generator>
+  <author> <name>%s </name> </author>
+  <title mode=\"escaped\" type=\"text/html\">%s </title>
+  <content type='xhtml'>
+    <div xmlns=\"http://www.w3.org/1999/xhtml\">
+<!--content goes here -->
+    </div>
+  </content>
+</entry>"
+  "Template for new Blogger entries.")
+
+;;}}}
+;;{{{ constants:
+
+(defconst gblogger-service-name "blogger"
+  "Service name for accessing  Blogger.")
+
+(defconst gblogger-base-url
+  "http://www.blogger.com/feeds/default/blogs"
+  "Base url for blogger access.")
+
+
+
+
+
+
+(defsubst gblogger-p (service)
+  "Check if this is blogger."
+  (declare (special gblogger-service-name))
+  (string-equal service gblogger-service-name))
+
+;;}}}
+;;{{{  blogger Authenticate
+
+(defsubst make-gblogger-auth ()
+  "Make a new gblogger auth handle."
+  (declare (special gblogger-service-name
+                    gblogger-user-email gblogger-user-password))
+  (make-g-auth :service gblogger-service-name
+               :email gblogger-user-email
+               :password gblogger-user-password))
+(defvar gblogger-auth-handle
+  (make-gblogger-auth)
+  "Gblogger auth handle.
+Holds user's email address, password, and the auth token received
+from the server.")
+
+;;}}}
+;;{{{ Define gblogger mode:
+
+(define-derived-mode gblogger-mode xml-mode
+  "Atom Blogger Interaction"
+  "Major mode for Blogger interaction\n\n
+\\{gblogger-mode-map"
+  (auto-fill-mode 1))
+
+(declaim (special gblogger-mode-map))
+(define-key gblogger-mode-map "\C-c\C-c" 'gblogger-publish)
+
+
+(defvar gblogger-this-url nil
+  "Buffer local variable that records URL we came from.")
+
+(make-variable-buffer-local 'gblogger-this-url)
+
+;;}}}
+;;{{{ Interactive Commands:
+
+;;;###autoload
+(defun gblogger-blog ()
+  "Retrieve and display feed of feeds after authenticating."
+  (interactive)
+  (declare (special gblogger-auth-handle
+                    g-atom-view-xsl
+                    g-curl-program g-curl-common-options
+                    g-cookie-options))
+  (g-auth-ensure-token gblogger-auth-handle)
+  (g-display-result
+   (format
+    "%s --location --header 'Authorization: GoogleLogin auth=%s' '%s' 2>/dev/null"
+    g-curl-program
+    (g-cookie "Auth" gblogger-auth-handle)
+    gblogger-base-url)
+   g-atom-view-xsl))
+;;;###autoload
+(defun gblogger-atom-display (url)
+  "Retrieve and display specified feed after authenticating."
+  (interactive
+   (list
+    (read-from-minibuffer "Feed: "
+                          (browse-url-url-at-point))))
+  (declare (special gblogger-auth-handle
+                    g-atom-view-xsl
+                    g-curl-program g-curl-common-options
+                    g-cookie-options))
+  (g-auth-ensure-token gblogger-auth-handle)
+  (g-display-result
+   (format
+    "%s --location --header 'Authorization: GoogleLogin auth=%s' '%s' 2>/dev/null"
+    g-curl-program
+    (g-cookie "Auth" gblogger-auth-handle)
+    url)
+   g-atom-view-xsl))
+
+(defun gblogger-get-entry (url)
+  "Retrieve specified entry.
+`url' is the URL of the entry"
+  (declare (special gblogger-auth-handle
+                    g-curl-program g-curl-common-options))
+  (g-auth-ensure-token gblogger-auth-handle)
+  (let ((buffer (get-buffer-create "*atom entry*"))
+        (nxml-auto-insert-xml-declaration-flag nil))
+    (save-excursion
+      (set-buffer buffer)
+      (insert
+       (g-get-result
+        (format
+         "%s %s %s  %s 2>/dev/null"
+         g-curl-program g-curl-common-options
+         (g-authorization gblogger-auth-handle)
+         url)))
+      (g-html-unescape-region (point-min) (point-max))
+      (gblogger-mode)
+      (setq gblogger-this-url url)
+      buffer)))
+
+;;;###autoload
+(defun gblogger-edit-entry (url)
+  "Retrieve entry and prepare it for editting.
+The retrieved entry is placed in a buffer ready for editing.
+`url' is the URL of the entry."
+  (interactive
+   (list
+    (read-from-minibuffer "Entry URL:")))
+  (declare (special gblogger-auth-handle
+                    g-curl-program g-curl-common-options))
+  (let ((buffer (gblogger-get-entry url)))
+    (save-excursion
+      (set-buffer buffer)
+      (setq gblogger-publish-action 'gblogger-put-entry)
+      (g-xsl-transform-region (point-min) (point-max)
+                              g-atom-edit-filter))
+    (switch-to-buffer buffer)
+    (goto-char (point-min))
+    (flush-lines "^ *$")
+    (goto-char (point-min))
+    (search-forward "<content" nil t)
+    (forward-line 1)
+    (message
+     (substitute-command-keys "Use \\[gblogger-publish] to publish your edits ."))))
+
+;;;###autoload
+(defun gblogger-new-entry (url)
+  "Create a new Blog post."
+  (interactive
+   (list
+    (read-from-minibuffer "Post URL:")))
+  (declare (special gblogger-auth-handle gblogger-new-entry-template
+                    gblogger-generator-name gblogger-publish-action))
+  (g-auth-ensure-token gblogger-auth-handle)
+  (let* ((title (read-string "Title: "))
+         (buffer (get-buffer-create title)))
+    (save-excursion
+      (set-buffer buffer)
+      (erase-buffer)
+      (gblogger-mode)
+      (setq gblogger-this-url url)
+      (goto-char (point-max))
+      (insert
+       (format gblogger-new-entry-template
+               gblogger-generator-name gblogger-generator-name
+               gblogger-author title)))
+    (switch-to-buffer buffer)
+    (setq gblogger-publish-action 'gblogger-post-entry)
+    (search-backward "<div" nil t)
+    (forward-line 1)
+    (message
+     (substitute-command-keys "Use \\[gblogger-publish] to
+publish your edits ."))))
+
+
+(defun gblogger-send-buffer-contents (http-method)
+  "Publish the Blog entry in the current buffer.
+http-method is either POST or PUT"
+  (declare (special g-cookie-options gblogger-auth-handle
+                    g-curl-program g-curl-common-options))
+  (unless (and (eq major-mode 'gblogger-mode)
+               gblogger-this-url)
+    (error "Not in a correctly initialized Atom Entry."))
+  (goto-char (point-min))
+  (let ((cl (format "-H Content-length:%s" (buffer-size))))
+    (shell-command-on-region
+     (point-min) (point-max)
+     (format
+      "%s %s %s %s %s -i -X %s --data-binary @- %s 2>/dev/null"
+      g-curl-program g-curl-common-options cl
+      (g-authorization gblogger-auth-handle)
+      g-cookie-options
+      http-method
+      gblogger-this-url)
+     (current-buffer) 'replace)
+    (list (g-http-headers (point-min) (point-max))
+          (g-http-body (point-min) (point-max)))))
+
+;;;###autoload
+(defun gblogger-post-entry ()
+  "Post buffer contents  as  updated entry."
+  (interactive)
+  (gblogger-send-buffer-contents "POST"))
+
+;;;###autoload
+(defun gblogger-put-entry ()
+  "PUT buffer contents as new entry."
+  (interactive)
+  (gblogger-send-buffer-contents "PUT"))
+
+;;;### autoload
+
+
+;;;### autoload
+;;;###autoload
+(defun gblogger-publish ()
+  "Publish current entry."
+  (interactive)
+  (declare (special gblogger-this-url gblogger-auth-handle
+                    gblogger-publish-action))
+  (unless (and (eq major-mode 'gblogger-mode)
+               gblogger-publish-action
+               (commandp gblogger-publish-action)
+               gblogger-this-url)
+    (error "Not in a correctly initialized Atom Entry."))
+  (call-interactively gblogger-publish-action)
+  (message "Publishing  to %s" gblogger-this-url))
+
+;;;### autoload
+(defun gblogger-delete-entry (url)
+  "Delete specified entry."
+  (interactive
+   (list
+    (read-from-minibuffer "Entry URL:")))
+  (declare (special gblogger-auth-handle))
+  (g-auth-ensure-token gblogger-auth-handle)
+  (shell-command
+   (format "%s %s %s -X DELETE %s %s"
+           g-curl-program g-curl-common-options
+           (g-authorization gblogger-auth-handle)
+           url
+           (g-curl-debug))))
+
+;;}}}
+(provide 'atom-blogger)
+;;{{{ end of file
+
+;;; local variables:
+;;; folded-file: t
+;;; byte-compile-dynamic: t
+;;; end:
+
+;;}}}

emacs.d/g-client/gcal-view.xsl

+<?xml version="1.0" encoding="utf-8"?>
+<!--
+Author: T. V. Raman <raman@cs.cornell.edu>
+License: GPL
+Copyright: This file is part of the g-client package.
+View GCal Events
+-->
+
+<xsl:stylesheet version="1.0"
+                xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+                xmlns:a="http://www.w3.org/2005/Atom"
+                xmlns:gd="http://schemas.google.com/g/2005" >
+  <xsl:output method="xml"  indent="yes"/>
+  <xsl:include href="gevent.xsl"/>
+  <xsl:template match="a:feed">
+    <html>
+      <head>
+        <title><xsl:value-of select="a:title" disable-output-escaping="yes"/></title>
+      </head>
+      <body>
+        <xsl:for-each  select="a:entry">
+          <xsl:sort select="gd:when/@startTime"
+                    data-type="text" order="ascending"/>
+        <xsl:apply-templates select="." />
+        </xsl:for-each>
+      </body>
+    </html>
+  </xsl:template>
+  
+</xsl:stylesheet>

emacs.d/g-client/gcal.el

+;;; gcal.el --- Google Calendar
+;;;$Id: gcal.el,v 1.30 2006/09/28 17:47:44 raman Exp $
+;;; $Author: raman $
+;;; Description:  Google Calendar
+;;; Keywords: Google   Atom API
+;;{{{  LCD Archive entry:
+
+;;; LCD Archive Entry:
+;;; gcal| T. V. Raman |raman@cs.cornell.edu
+;;; An emacs interface to Reader|
+;;; $Date: 2006/09/28 17:47:44 $ |
+;;;  $Revision: 1.30 $ |
+;;; Location undetermined
+;;; License: GPL
+;;;
+
+;;}}}
+;;{{{ Copyright:
+
+;;; Copyright (c) 2006 and later, Google Inc.
+;;; All rights reserved.
+
+;;; Redistribution and use in source and binary forms, with or without modification,
+;;; are permitted provided that the following conditions are met:
+
+;;;     * Redistributions of source code must retain the above copyright notice,
+;;;       this list of conditions and the following disclaimer.
+;;;     * Redistributions in binary form must reproduce the above copyright notice,
+;;;       this list of conditions and the following disclaimer in the documentation
+;;;       and/or other materials provided with the distribution.
+;;;     * The name of the author may not be used to endorse or promote products
+;;;       derived from this software without specific prior written permission.
+
+;;; THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+;;; AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+;;; IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+;;; ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+;;; LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR