SampleSyncAdapter sample code.
diff --git a/samples/SampleSyncAdapter/samplesyncadapter_server/main.py b/samples/SampleSyncAdapter/samplesyncadapter_server/main.py
new file mode 100644
index 0000000..2d7c5c7
--- /dev/null
+++ b/samples/SampleSyncAdapter/samplesyncadapter_server/main.py
@@ -0,0 +1,173 @@
+#!/usr/bin/python2.5
+
+# Copyright (C) 2010 The Android Open Source Project
+#
+# 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.
+
+"""Handlers for Sample SyncAdapter services.
+
+Contains several RequestHandler subclasses used to handle post operations.
+This script is designed to be run directly as a WSGI application.
+
+ Authenticate: Handles user requests for authentication.
+ FetchFriends: Handles user requests for friend list.
+ FriendData: Stores information about user's friends.
+"""
+
+import cgi
+from datetime import datetime
+from django.utils import simplejson
+from google.appengine.api import users
+from google.appengine.ext import db
+from google.appengine.ext import webapp
+from model import datastore
+import wsgiref.handlers
+
+
+class Authenticate(webapp.RequestHandler):
+ """Handles requests for login and authentication.
+
+ UpdateHandler only accepts post events. It expects each
+ request to include username and password fields. It returns authtoken
+ after successful authentication and "invalid credentials" error otherwise.
+ """
+
+ def post(self):
+ self.username = self.request.get('username')
+ self.password = self.request.get('password')
+ password = datastore.UserCredentials.get(self.username)
+ if password == self.password:
+ self.response.set_status(200, 'OK')
+ # return the password as AuthToken
+ self.response.out.write(password)
+ else:
+ self.response.set_status(401, 'Invalid Credentials')
+
+
+class FetchFriends(webapp.RequestHandler):
+ """Handles requests for fetching user's friendlist.
+
+ UpdateHandler only accepts post events. It expects each
+ request to include username and authtoken. If the authtoken is valid
+ it returns user's friend info in JSON format.It uses helper
+ class FriendData to fetch user's friendlist.
+ """
+
+ def post(self):
+ self.username = self.request.get('username')
+ self.password = self.request.get('password')
+ self.timestamp = None
+ timestamp = self.request.get('timestamp')
+ if timestamp:
+ self.timestamp = datetime.strptime(timestamp, '%Y/%m/%d %H:%M')
+ password = datastore.UserCredentials.get(self.username)
+ if password == self.password:
+ self.friend_list = []
+ friends = datastore.UserFriends.get_friends(self.username)
+ if friends:
+ for friend in friends:
+ friend_handle = getattr(friend, 'friend_handle')
+
+ if self.timestamp is None or getattr(friend, 'updated') > self.timestamp:
+ if (getattr(friend, 'deleted')) == True:
+ friend = {}
+ friend['u'] = friend_handle
+ friend['d'] = 'true'
+ friend['i'] = str(datastore.User.get_user_id(friend_handle))
+ self.friend_list.append(friend)
+ else:
+ FriendsData(self.friend_list, friend_handle)
+ else:
+ if datastore.User.get_user_last_updated(friend_handle) > self.timestamp:
+ FriendsData(self.friend_list, friend_handle)
+ self.response.set_status(200)
+ self.response.out.write(toJSON(self.friend_list))
+ else:
+ self.response.set_status(401, 'Invalid Credentials')
+
+class FetchStatus(webapp.RequestHandler):
+ """Handles requests fetching friend statuses.
+
+ UpdateHandler only accepts post events. It expects each
+ request to include username and authtoken. If the authtoken is valid
+ it returns status info in JSON format.
+ """
+
+ def post(self):
+ self.username = self.request.get('username')
+ self.password = self.request.get('password')
+ password = datastore.UserCredentials.get(self.username)
+ if password == self.password:
+ self.status_list = []
+ friends = datastore.UserFriends.get_friends(self.username)
+ if friends:
+ for friend in friends:
+ friend_handle = getattr(friend, 'friend_handle')
+ status_text = datastore.User.get_user_status(friend_handle)
+ user_id = datastore.User.get_user_id(friend_handle)
+ status = {}
+ status['i'] = str(user_id)
+ status['s'] = status_text
+ self.status_list.append(status)
+ self.response.set_status(200)
+ self.response.out.write(toJSON(self.status_list))
+ else:
+ self.response.set_status(401, 'Invalid Credentials')
+
+ def toJSON(self):
+ """Dumps the data represented by the object to JSON for wire transfer."""
+ return simplejson.dumps(self.friend_list)
+
+
+def toJSON(object):
+ """Dumps the data represented by the object to JSON for wire transfer."""
+ return simplejson.dumps(object)
+
+class FriendsData(object):
+ """Holds data for user's friends.
+
+ This class knows how to serialize itself to JSON.
+ """
+ __FIELD_MAP = {
+ 'handle': 'u',
+ 'firstname': 'f',
+ 'lastname': 'l',
+ 'status': 's',
+ 'phone_home': 'h',
+ 'phone_office': 'o',
+ 'phone_mobile': 'm',
+ 'email': 'e',
+ }
+
+ def __init__(self, friend_list, username):
+ obj = datastore.User.get_user_info(username)
+ friend = {}
+ for obj_name, json_name in self.__FIELD_MAP.items():
+ if hasattr(obj, obj_name):
+ friend[json_name] = str(getattr(obj, obj_name))
+ friend['i'] = str(obj.key().id())
+ friend_list.append(friend)
+
+
+def main():
+ application = webapp.WSGIApplication(
+ [('/auth', Authenticate),
+ ('/login', Authenticate),
+ ('/fetch_friend_updates', FetchFriends),
+ ('/fetch_status', FetchStatus),
+ ],
+ debug=True)
+ wsgiref.handlers.CGIHandler().run(application)
+
+if __name__ == "__main__":
+ main()
\ No newline at end of file