Commits

Anonymous committed db8e1f8

Rename news feed client to something more descriptive

  • Participants
  • Parent commits 1a0d8df

Comments (0)

Files changed (16)

File examples/client/app.yaml

-application: facebook-example
-version: 1
-runtime: python
-api_version: 1
-
-handlers:
-- url: /static
-  static_dir: static
-
-- url: /favicon\.ico
-  static_files: static/favicon.ico
-  upload: static/favicon.ico
-
-- url: /robots\.txt
-  static_files: static/robots.txt
-  upload: static/robots.txt
-
-- url: /.*
-  script: facebookclient.py

File examples/client/facebookclient.py

-#!/usr/bin/env python
-#
-# Copyright 2010 Facebook
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-#     http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-"""A Facebook stream client written against the Facebook Graph API."""
-
-FACEBOOK_APP_ID = "your app id"
-FACEBOOK_APP_SECRET = "your app secret"
-
-import datetime
-import facebook
-import os
-import os.path
-import wsgiref.handlers
-
-from google.appengine.ext import db
-from google.appengine.ext import webapp
-from google.appengine.ext.webapp import util
-from google.appengine.ext.webapp import template
-
-
-class User(db.Model):
-    id = db.StringProperty(required=True)
-    created = db.DateTimeProperty(auto_now_add=True)
-    updated = db.DateTimeProperty(auto_now=True)
-    name = db.StringProperty(required=True)
-    profile_url = db.StringProperty(required=True)
-    access_token = db.StringProperty(required=True)
-
-
-class BaseHandler(webapp.RequestHandler):
-    """Provides access to the active Facebook user in self.current_user
-
-    The property is lazy-loaded on first access, using the cookie saved
-    by the Facebook JavaScript SDK to determine the user ID of the active
-    user. See http://developers.facebook.com/docs/authentication/ for
-    more information.
-    """
-    @property
-    def current_user(self):
-        """Returns the active user, or None if the user has not logged in."""
-        if not hasattr(self, "_current_user"):
-            self._current_user = None
-            cookie = facebook.get_user_from_cookie(
-                self.request.cookies, FACEBOOK_APP_ID, FACEBOOK_APP_SECRET)
-            if cookie:
-                # Store a local instance of the user data so we don't need
-                # a round-trip to Facebook on every request
-                user = User.get_by_key_name(cookie["uid"])
-                if not user:
-                    graph = facebook.GraphAPI(cookie["oauth_access_token"])
-                    profile = graph.get_object("me")
-                    user = User(key_name=str(profile["id"]),
-                                id=str(profile["id"]),
-                                name=profile["name"],
-                                profile_url=profile["profile_url"],
-                                access_token=cookie["oauth_access_token"])
-                    user.put()
-                elif user.access_token != cookie["oauth_access_token"]:
-                    user.access_token = cookie["oauth_access_token"]
-                    user.put()
-                self._current_user = user
-        return self._current_user
-
-    @property
-    def graph(self):
-        """Returns a Graph API client for the current user."""
-        if not hasattr(self, "_graph"):
-            if self.current_user:
-                self._graph = facebook.GraphAPI(self.current_user.access_token)
-            else:
-                self._graph = facebook.GraphAPI()
-        return self._graph
-
-    def render(self, path, **kwargs):
-        args = dict(current_user=self.current_user,
-                    facebook_app_id=FACEBOOK_APP_ID)
-        args.update(kwargs)
-        path = os.path.join(os.path.dirname(__file__), "templates", path)
-        self.response.out.write(template.render(path, args))
-
-
-class HomeHandler(BaseHandler):
-    def get(self):
-        if not self.current_user:
-            self.render("index.html")
-            return
-        news_feed = self.graph.get_connections("me", "home")
-        for post in news_feed["data"]:
-            post["created_time"] = datetime.datetime.strptime(
-                post["created_time"], "%Y-%m-%dT%H:%M:%S-0700") + \
-                datetime.timedelta(hours=7)
-        self.render("home.html", news_feed=news_feed)
-
-
-class PostHandler(BaseHandler):
-    def post(self):
-        message = self.request.get("message")
-        if not self.current_user or not message:
-            self.redirect("/")
-            return
-        try:
-            self.graph.put_wall_post(message)
-        except:
-            pass
-        self.redirect("/")
-
-
-def main():
-    debug = os.environ.get("SERVER_SOFTWARE", "").startswith("Development/")
-    util.run_wsgi_app(webapp.WSGIApplication([
-        (r"/", HomeHandler),
-        (r"/post", PostHandler),
-    ], debug=debug))
-
-
-if __name__ == "__main__":
-    main()

File examples/client/static/base.css

-body {
-  background: white;
-  margin: 0;
-}
-
-body,
-input,
-textarea {
-  color: #333;
-  font-family: "Lucida Grande", Tahoma, Verdana, Arial, sans-serif;
-  font-size: 13px;
-}
-
-a {
-  color: #3b5998;
-  text-decoration: none;
-}
-
-a:hover {
-  text-decoration: underline;
-}
-
-img {
-  border: 0;
-}
-
-table {
-  border: 0;
-  border-collapse: collapse;
-  border-spacing: 0;
-}
-
-td {
-  border: 0;
-  padding: 0;
-}
-
-#promo {
-  background: #eee;
-  padding: 8px;
-  border-bottom: 1px solid #ccc;
-  color: gray;
-  text-align: center;
-}
-
-#body {
-  max-width: 800px;
-  margin: auto;
-  padding: 20px;
-}
-
-#header h1 {
-  margin: 0;
-  padding: 0;
-  font-size: 15px;
-  line-height: 25px;
-}
-
-#header .button {
-  float: right;
-}
-
-#content {
-  clear: both;
-  margin-top: 15px;
-}
-
-.clearfix:after {
-  clear: both;
-  content: ".";
-  display: block;
-  font-size: 0;
-  height: 0;
-  line-height: 0;
-  visibility: hidden;
-}
-
-.clearfix {
-  display: block;
-  zoom: 1;
-}
-
-.feed .entry {
-  padding-top: 9px;
-  border-top: 1px solid #eee;
-  margin-top: 9px;
-}
-
-.feed .entry .profile {
-  float: left;
-  line-height: 0;
-}
-
-.feed .entry .profile img {
-  width: 50px;
-  height: 50px;
-}
-
-.feed .entry .body {
-  margin-left: 60px;
-}
-
-.feed .entry .name {
-  font-weight: bold;
-}
-
-.feed .entry .attachment {
-  font-size: 11px;
-  line-height: 15px;
-  margin-top: 8px;
-  margin-bottom: 8px;
-  color: gray;
-}
-
-.feed .entry .attachment.nopicture {
-  border-left: 2px solid #ccc;
-  padding-left: 10px;
-}
-
-.feed .entry .attachment .picture {
-  line-height: 0;
-  float: left;
-  padding-right: 10px;
-}
-
-.feed .entry .attachment .picture img {
-  border: 1px solid #ccc;
-  padding: 3px;
-}
-
-.feed .entry .attachment .picture a:hover img {
-  border-color: #3b5998;
-}
-
-.feed .entry .info {
-  font-size: 11px;
-  line-height: 17px;
-  margin-top: 3px;
-  color: gray;
-}
-
-.feed .entry .info.icon {
-  background-position: left center;
-  background-repeat: no-repeat;
-  padding-left: 20px;
-}
-
-.feed .post .textbox {
-  margin-right: 6px;
-}
-
-.feed .post .textbox textarea {
-  margin: 0;
-  border: 1px solid #bbb;
-  border-top-color: #aeaeae;
-  padding: 2px;
-  width: 100%;
-}
-
-.feed .post .buttons {
-  text-align: right;
-}

File examples/client/static/favicon.ico

Removed
Old image

File examples/client/static/robots.txt

-User-Agent: *
-Disallow: /

File examples/client/templates/base.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">
-  <head>
-    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/> 
-    <title>{% block title %}Facebook Client Example{% endblock %}</title>
-    <link rel="stylesheet" href="/static/base.css" type="text/css"/>
-    {% block head %}{% endblock %}
-  </head>
-  <body>
-    <div id="promo">This application is a demo of the <a href="http://developers.facebook.com/docs/api">Facebook Graph API</a>, the core part of the <a href="http://developers.facebook.com/">Facebook Platform</a>. <a href="http://github.com/facebook/python-sdk/blob/master/examples/client/facebookclient.py">See source code &raquo;</a></div>
-    <div id="body">{% block body %}{% endblock %}</div>
-    <div id="fb-root"></div>
-    <script>
-      window.fbAsyncInit = function() {
-        FB.init({appId: '{{ facebook_app_id }}', status: true, cookie: true, xfbml: true});
-        FB.Event.subscribe('auth.statusChange', function(response) {
-          window.location.reload();
-        });
-      };
-      (function() {
-        var e = document.createElement('script');
-        e.type = 'text/javascript';
-        e.src = document.location.protocol + '//connect.facebook.net/en_US/all.js';
-        e.async = true;
-        document.getElementById('fb-root').appendChild(e);
-      }());
-    </script>
-  </body>
-</html>

File examples/client/templates/home.html

-{% extends "base.html" %}
-
-{% block body %}
-  <div id="header">
-    <div class="button"><fb:login-button autologoutlink="true" perms="read_stream,publish_stream"></fb:login-button></div>
-    <h1>Facebook Client Demo</h1>
-  </div>
-  <div id="content" class="feed">
-
-    <div class="entry post clearfix">
-      <div class="profile"><a href="{{ current_user.profile_url|escape }}"><img src="http://graph.facebook.com/{{ current_user.id }}/picture"/></a></div>
-      <div class="body">
-	<form action="/post" method="post">
-	  <div class="textbox"><textarea name="message"></textarea></div>
-	  <div class="buttons"><input type="submit" value="Share"/></div>
-	</form>
-      </div>
-    </div>
-
-    {% for post in news_feed.data %}
-      <div class="entry clearfix">
-        <div class="profile"><a href="http://www.facebook.com/profile.php?id={{ post.from.id }}"><img src="http://graph.facebook.com/{{ post.from.id }}/picture"/></a></div>
-	<div class="body">
-          <div class="message">
-	    <a class="name" href="http://www.facebook.com/profile.php?id={{ post.from.id }}">{{ post.from.name|escape }}</a>
-            {% if post.message %}{{ post.message|escape }}{% endif %}
-	  </div>
-	  {% if post.caption or post.picture %}
-	    <div class="attachment clearfix{% if not post.picture %} nopicture{% endif %}">
-	      {% if post.picture %}
-	        <div class="picture"><a href="{{ post.link|escape }}"><img src="{{ post.picture|escape }}"/></a></div>
-	      {% endif %}
-	      {% if post.name %}
-	        <div class="name"><a href="{{ post.link|escape }}">{{ post.name|escape }}</a></div>
-	      {% endif %}
-	      {% if post.caption %}
-	        <div class="caption">{{ post.caption|escape }}</div>
-	      {% endif %}
-	      {% if post.description %}
-	        <div class="description">{{ post.description|escape }}</div>
-	      {% endif %}
-	    </div>
-	  {% endif %}
-	  <div class="info{% if post.icon %} icon{% endif %}"{% if post.icon %} style="background-image:url('{{ post.icon|escape }}')"{% endif %}>
-	    {{ post.created_time|timesince }} ago
-	  </div>
-	</div>
-      </div>
-    {% endfor %}
-
-  </div>
-{% endblock %}

File examples/client/templates/index.html

-{% extends "base.html" %}
-
-{% block body %}
-  <p>This application is a simple Facebook client. It shows you your News Feed and enables you to post status messages back to your profile. It is designed to demonstrate the use of the <a href="http://developers.facebook.com/docs/api">Facebook Graph API</a>, the core part of the <a href="http://developers.facebook.com/">Facebook Platform</a>. To get started, log in to Facebook below:</p>
-  <fb:login-button perms="read_stream,publish_stream"></fb:login-button>
-  <p>You can <a href="http://github.com/facebook/python-sdk/blob/master/examples/client/facebookclient.py">download the source code</a> to this application on <a href="http://github.com/facebook/python-sdk">GitHub</a>.</p>
-{% endblock %}

File examples/newsfeed/app.yaml

+application: facebook-example
+version: 1
+runtime: python
+api_version: 1
+
+handlers:
+- url: /static
+  static_dir: static
+
+- url: /favicon\.ico
+  static_files: static/favicon.ico
+  upload: static/favicon.ico
+
+- url: /robots\.txt
+  static_files: static/robots.txt
+  upload: static/robots.txt
+
+- url: /.*
+  script: facebookclient.py

File examples/newsfeed/facebookclient.py

+#!/usr/bin/env python
+#
+# Copyright 2010 Facebook
+#
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License. You may obtain
+# a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+
+"""A Facebook stream client written against the Facebook Graph API."""
+
+FACEBOOK_APP_ID = "your app id"
+FACEBOOK_APP_SECRET = "your app secret"
+
+import datetime
+import facebook
+import os
+import os.path
+import wsgiref.handlers
+
+from google.appengine.ext import db
+from google.appengine.ext import webapp
+from google.appengine.ext.webapp import util
+from google.appengine.ext.webapp import template
+
+
+class User(db.Model):
+    id = db.StringProperty(required=True)
+    created = db.DateTimeProperty(auto_now_add=True)
+    updated = db.DateTimeProperty(auto_now=True)
+    name = db.StringProperty(required=True)
+    profile_url = db.StringProperty(required=True)
+    access_token = db.StringProperty(required=True)
+
+
+class BaseHandler(webapp.RequestHandler):
+    """Provides access to the active Facebook user in self.current_user
+
+    The property is lazy-loaded on first access, using the cookie saved
+    by the Facebook JavaScript SDK to determine the user ID of the active
+    user. See http://developers.facebook.com/docs/authentication/ for
+    more information.
+    """
+    @property
+    def current_user(self):
+        """Returns the active user, or None if the user has not logged in."""
+        if not hasattr(self, "_current_user"):
+            self._current_user = None
+            cookie = facebook.get_user_from_cookie(
+                self.request.cookies, FACEBOOK_APP_ID, FACEBOOK_APP_SECRET)
+            if cookie:
+                # Store a local instance of the user data so we don't need
+                # a round-trip to Facebook on every request
+                user = User.get_by_key_name(cookie["uid"])
+                if not user:
+                    graph = facebook.GraphAPI(cookie["oauth_access_token"])
+                    profile = graph.get_object("me")
+                    user = User(key_name=str(profile["id"]),
+                                id=str(profile["id"]),
+                                name=profile["name"],
+                                profile_url=profile["profile_url"],
+                                access_token=cookie["oauth_access_token"])
+                    user.put()
+                elif user.access_token != cookie["oauth_access_token"]:
+                    user.access_token = cookie["oauth_access_token"]
+                    user.put()
+                self._current_user = user
+        return self._current_user
+
+    @property
+    def graph(self):
+        """Returns a Graph API client for the current user."""
+        if not hasattr(self, "_graph"):
+            if self.current_user:
+                self._graph = facebook.GraphAPI(self.current_user.access_token)
+            else:
+                self._graph = facebook.GraphAPI()
+        return self._graph
+
+    def render(self, path, **kwargs):
+        args = dict(current_user=self.current_user,
+                    facebook_app_id=FACEBOOK_APP_ID)
+        args.update(kwargs)
+        path = os.path.join(os.path.dirname(__file__), "templates", path)
+        self.response.out.write(template.render(path, args))
+
+
+class HomeHandler(BaseHandler):
+    def get(self):
+        if not self.current_user:
+            self.render("index.html")
+            return
+        news_feed = self.graph.get_connections("me", "home")
+        for post in news_feed["data"]:
+            post["created_time"] = datetime.datetime.strptime(
+                post["created_time"], "%Y-%m-%dT%H:%M:%S-0700") + \
+                datetime.timedelta(hours=7)
+        self.render("home.html", news_feed=news_feed)
+
+
+class PostHandler(BaseHandler):
+    def post(self):
+        message = self.request.get("message")
+        if not self.current_user or not message:
+            self.redirect("/")
+            return
+        try:
+            self.graph.put_wall_post(message)
+        except:
+            pass
+        self.redirect("/")
+
+
+def main():
+    debug = os.environ.get("SERVER_SOFTWARE", "").startswith("Development/")
+    util.run_wsgi_app(webapp.WSGIApplication([
+        (r"/", HomeHandler),
+        (r"/post", PostHandler),
+    ], debug=debug))
+
+
+if __name__ == "__main__":
+    main()

File examples/newsfeed/static/base.css

+body {
+  background: white;
+  margin: 0;
+}
+
+body,
+input,
+textarea {
+  color: #333;
+  font-family: "Lucida Grande", Tahoma, Verdana, Arial, sans-serif;
+  font-size: 13px;
+}
+
+a {
+  color: #3b5998;
+  text-decoration: none;
+}
+
+a:hover {
+  text-decoration: underline;
+}
+
+img {
+  border: 0;
+}
+
+table {
+  border: 0;
+  border-collapse: collapse;
+  border-spacing: 0;
+}
+
+td {
+  border: 0;
+  padding: 0;
+}
+
+#promo {
+  background: #eee;
+  padding: 8px;
+  border-bottom: 1px solid #ccc;
+  color: gray;
+  text-align: center;
+}
+
+#body {
+  max-width: 800px;
+  margin: auto;
+  padding: 20px;
+}
+
+#header h1 {
+  margin: 0;
+  padding: 0;
+  font-size: 15px;
+  line-height: 25px;
+}
+
+#header .button {
+  float: right;
+}
+
+#content {
+  clear: both;
+  margin-top: 15px;
+}
+
+.clearfix:after {
+  clear: both;
+  content: ".";
+  display: block;
+  font-size: 0;
+  height: 0;
+  line-height: 0;
+  visibility: hidden;
+}
+
+.clearfix {
+  display: block;
+  zoom: 1;
+}
+
+.feed .entry {
+  padding-top: 9px;
+  border-top: 1px solid #eee;
+  margin-top: 9px;
+}
+
+.feed .entry .profile {
+  float: left;
+  line-height: 0;
+}
+
+.feed .entry .profile img {
+  width: 50px;
+  height: 50px;
+}
+
+.feed .entry .body {
+  margin-left: 60px;
+}
+
+.feed .entry .name {
+  font-weight: bold;
+}
+
+.feed .entry .attachment {
+  font-size: 11px;
+  line-height: 15px;
+  margin-top: 8px;
+  margin-bottom: 8px;
+  color: gray;
+}
+
+.feed .entry .attachment.nopicture {
+  border-left: 2px solid #ccc;
+  padding-left: 10px;
+}
+
+.feed .entry .attachment .picture {
+  line-height: 0;
+  float: left;
+  padding-right: 10px;
+}
+
+.feed .entry .attachment .picture img {
+  border: 1px solid #ccc;
+  padding: 3px;
+}
+
+.feed .entry .attachment .picture a:hover img {
+  border-color: #3b5998;
+}
+
+.feed .entry .info {
+  font-size: 11px;
+  line-height: 17px;
+  margin-top: 3px;
+  color: gray;
+}
+
+.feed .entry .info.icon {
+  background-position: left center;
+  background-repeat: no-repeat;
+  padding-left: 20px;
+}
+
+.feed .post .textbox {
+  margin-right: 6px;
+}
+
+.feed .post .textbox textarea {
+  margin: 0;
+  border: 1px solid #bbb;
+  border-top-color: #aeaeae;
+  padding: 2px;
+  width: 100%;
+}
+
+.feed .post .buttons {
+  text-align: right;
+}

File examples/newsfeed/static/favicon.ico

Added
New image

File examples/newsfeed/static/robots.txt

+User-Agent: *
+Disallow: /

File examples/newsfeed/templates/base.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">
+  <head>
+    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/> 
+    <title>{% block title %}Facebook Client Example{% endblock %}</title>
+    <link rel="stylesheet" href="/static/base.css" type="text/css"/>
+    {% block head %}{% endblock %}
+  </head>
+  <body>
+    <div id="promo">This application is a demo of the <a href="http://developers.facebook.com/docs/api">Facebook Graph API</a>, the core part of the <a href="http://developers.facebook.com/">Facebook Platform</a>. <a href="http://github.com/facebook/python-sdk/blob/master/examples/client/facebookclient.py">See source code &raquo;</a></div>
+    <div id="body">{% block body %}{% endblock %}</div>
+    <div id="fb-root"></div>
+    <script>
+      window.fbAsyncInit = function() {
+        FB.init({appId: '{{ facebook_app_id }}', status: true, cookie: true, xfbml: true});
+        FB.Event.subscribe('auth.statusChange', function(response) {
+          window.location.reload();
+        });
+      };
+      (function() {
+        var e = document.createElement('script');
+        e.type = 'text/javascript';
+        e.src = document.location.protocol + '//connect.facebook.net/en_US/all.js';
+        e.async = true;
+        document.getElementById('fb-root').appendChild(e);
+      }());
+    </script>
+  </body>
+</html>

File examples/newsfeed/templates/home.html

+{% extends "base.html" %}
+
+{% block body %}
+  <div id="header">
+    <div class="button"><fb:login-button autologoutlink="true" perms="read_stream,publish_stream"></fb:login-button></div>
+    <h1>Facebook Client Demo</h1>
+  </div>
+  <div id="content" class="feed">
+
+    <div class="entry post clearfix">
+      <div class="profile"><a href="{{ current_user.profile_url|escape }}"><img src="http://graph.facebook.com/{{ current_user.id }}/picture"/></a></div>
+      <div class="body">
+	<form action="/post" method="post">
+	  <div class="textbox"><textarea name="message"></textarea></div>
+	  <div class="buttons"><input type="submit" value="Share"/></div>
+	</form>
+      </div>
+    </div>
+
+    {% for post in news_feed.data %}
+      <div class="entry clearfix">
+        <div class="profile"><a href="http://www.facebook.com/profile.php?id={{ post.from.id }}"><img src="http://graph.facebook.com/{{ post.from.id }}/picture"/></a></div>
+	<div class="body">
+          <div class="message">
+	    <a class="name" href="http://www.facebook.com/profile.php?id={{ post.from.id }}">{{ post.from.name|escape }}</a>
+            {% if post.message %}{{ post.message|escape }}{% endif %}
+	  </div>
+	  {% if post.caption or post.picture %}
+	    <div class="attachment clearfix{% if not post.picture %} nopicture{% endif %}">
+	      {% if post.picture %}
+	        <div class="picture"><a href="{{ post.link|escape }}"><img src="{{ post.picture|escape }}"/></a></div>
+	      {% endif %}
+	      {% if post.name %}
+	        <div class="name"><a href="{{ post.link|escape }}">{{ post.name|escape }}</a></div>
+	      {% endif %}
+	      {% if post.caption %}
+	        <div class="caption">{{ post.caption|escape }}</div>
+	      {% endif %}
+	      {% if post.description %}
+	        <div class="description">{{ post.description|escape }}</div>
+	      {% endif %}
+	    </div>
+	  {% endif %}
+	  <div class="info{% if post.icon %} icon{% endif %}"{% if post.icon %} style="background-image:url('{{ post.icon|escape }}')"{% endif %}>
+	    {{ post.created_time|timesince }} ago
+	  </div>
+	</div>
+      </div>
+    {% endfor %}
+
+  </div>
+{% endblock %}

File examples/newsfeed/templates/index.html

+{% extends "base.html" %}
+
+{% block body %}
+  <p>This application is a simple Facebook client. It shows you your News Feed and enables you to post status messages back to your profile. It is designed to demonstrate the use of the <a href="http://developers.facebook.com/docs/api">Facebook Graph API</a>, the core part of the <a href="http://developers.facebook.com/">Facebook Platform</a>. To get started, log in to Facebook below:</p>
+  <fb:login-button perms="read_stream,publish_stream"></fb:login-button>
+  <p>You can <a href="http://github.com/facebook/python-sdk/blob/master/examples/client/facebookclient.py">download the source code</a> to this application on <a href="http://github.com/facebook/python-sdk">GitHub</a>.</p>
+{% endblock %}