blob: 2d7c5c78e39d88d634d34289596e671d0a70a3ae [file] [log] [blame]
Megha Joshi00bf0f02009-11-18 14:54:03 -08001#!/usr/bin/python2.5
2
3# Copyright (C) 2010 The Android Open Source Project
4#
5# Licensed under the Apache License, Version 2.0 (the "License"); you may not
6# use this file except in compliance with the License. You may obtain a copy of
7# the License at
8#
9# http://www.apache.org/licenses/LICENSE-2.0
10#
11# Unless required by applicable law or agreed to in writing, software
12# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
13# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
14# License for the specific language governing permissions and limitations under
15# the License.
16
17"""Handlers for Sample SyncAdapter services.
18
19Contains several RequestHandler subclasses used to handle post operations.
20This script is designed to be run directly as a WSGI application.
21
22 Authenticate: Handles user requests for authentication.
23 FetchFriends: Handles user requests for friend list.
24 FriendData: Stores information about user's friends.
25"""
26
27import cgi
28from datetime import datetime
29from django.utils import simplejson
30from google.appengine.api import users
31from google.appengine.ext import db
32from google.appengine.ext import webapp
33from model import datastore
34import wsgiref.handlers
35
36
37class Authenticate(webapp.RequestHandler):
38 """Handles requests for login and authentication.
39
40 UpdateHandler only accepts post events. It expects each
41 request to include username and password fields. It returns authtoken
42 after successful authentication and "invalid credentials" error otherwise.
43 """
44
45 def post(self):
46 self.username = self.request.get('username')
47 self.password = self.request.get('password')
48 password = datastore.UserCredentials.get(self.username)
49 if password == self.password:
50 self.response.set_status(200, 'OK')
51 # return the password as AuthToken
52 self.response.out.write(password)
53 else:
54 self.response.set_status(401, 'Invalid Credentials')
55
56
57class FetchFriends(webapp.RequestHandler):
58 """Handles requests for fetching user's friendlist.
59
60 UpdateHandler only accepts post events. It expects each
61 request to include username and authtoken. If the authtoken is valid
62 it returns user's friend info in JSON format.It uses helper
63 class FriendData to fetch user's friendlist.
64 """
65
66 def post(self):
67 self.username = self.request.get('username')
68 self.password = self.request.get('password')
69 self.timestamp = None
70 timestamp = self.request.get('timestamp')
71 if timestamp:
72 self.timestamp = datetime.strptime(timestamp, '%Y/%m/%d %H:%M')
73 password = datastore.UserCredentials.get(self.username)
74 if password == self.password:
75 self.friend_list = []
76 friends = datastore.UserFriends.get_friends(self.username)
77 if friends:
78 for friend in friends:
79 friend_handle = getattr(friend, 'friend_handle')
80
81 if self.timestamp is None or getattr(friend, 'updated') > self.timestamp:
82 if (getattr(friend, 'deleted')) == True:
83 friend = {}
84 friend['u'] = friend_handle
85 friend['d'] = 'true'
86 friend['i'] = str(datastore.User.get_user_id(friend_handle))
87 self.friend_list.append(friend)
88 else:
89 FriendsData(self.friend_list, friend_handle)
90 else:
91 if datastore.User.get_user_last_updated(friend_handle) > self.timestamp:
92 FriendsData(self.friend_list, friend_handle)
93 self.response.set_status(200)
94 self.response.out.write(toJSON(self.friend_list))
95 else:
96 self.response.set_status(401, 'Invalid Credentials')
97
98class FetchStatus(webapp.RequestHandler):
99 """Handles requests fetching friend statuses.
100
101 UpdateHandler only accepts post events. It expects each
102 request to include username and authtoken. If the authtoken is valid
103 it returns status info in JSON format.
104 """
105
106 def post(self):
107 self.username = self.request.get('username')
108 self.password = self.request.get('password')
109 password = datastore.UserCredentials.get(self.username)
110 if password == self.password:
111 self.status_list = []
112 friends = datastore.UserFriends.get_friends(self.username)
113 if friends:
114 for friend in friends:
115 friend_handle = getattr(friend, 'friend_handle')
116 status_text = datastore.User.get_user_status(friend_handle)
117 user_id = datastore.User.get_user_id(friend_handle)
118 status = {}
119 status['i'] = str(user_id)
120 status['s'] = status_text
121 self.status_list.append(status)
122 self.response.set_status(200)
123 self.response.out.write(toJSON(self.status_list))
124 else:
125 self.response.set_status(401, 'Invalid Credentials')
126
127 def toJSON(self):
128 """Dumps the data represented by the object to JSON for wire transfer."""
129 return simplejson.dumps(self.friend_list)
130
131
132def toJSON(object):
133 """Dumps the data represented by the object to JSON for wire transfer."""
134 return simplejson.dumps(object)
135
136class FriendsData(object):
137 """Holds data for user's friends.
138
139 This class knows how to serialize itself to JSON.
140 """
141 __FIELD_MAP = {
142 'handle': 'u',
143 'firstname': 'f',
144 'lastname': 'l',
145 'status': 's',
146 'phone_home': 'h',
147 'phone_office': 'o',
148 'phone_mobile': 'm',
149 'email': 'e',
150 }
151
152 def __init__(self, friend_list, username):
153 obj = datastore.User.get_user_info(username)
154 friend = {}
155 for obj_name, json_name in self.__FIELD_MAP.items():
156 if hasattr(obj, obj_name):
157 friend[json_name] = str(getattr(obj, obj_name))
158 friend['i'] = str(obj.key().id())
159 friend_list.append(friend)
160
161
162def main():
163 application = webapp.WSGIApplication(
164 [('/auth', Authenticate),
165 ('/login', Authenticate),
166 ('/fetch_friend_updates', FetchFriends),
167 ('/fetch_status', FetchStatus),
168 ],
169 debug=True)
170 wsgiref.handlers.CGIHandler().run(application)
171
172if __name__ == "__main__":
173 main()