-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathput-point.py
150 lines (118 loc) · 5.22 KB
/
put-point.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
from __future__ import print_function
import boto3
from boto3.dynamodb.conditions import Key, Attr
from decimal import *
# Helper for quering DynamoDB table
def dynamo_request(table_obj, request_dict):
resp = table_obj.get_item(Key=request_dict)
if resp.has_key('Item') and resp['Item']:
return resp['Item']
else:
return None
# Helper for put new item to DynamoDB table
def dynamo_put(table_obj, item_dict):
try:
resp = table_obj.put_item(Item=item_dict)
if resp:
if resp['ResponseMetadata']['HTTPStatusCode'] != 200:
return None
except:
return None
return True
# Helper for updating item in DynamoDB table
def dynamo_update(table_obj, request_dict, value_dict):
resp = table_obj.get_item(Key=request_dict)
if resp.has_key('Item') and resp['Item']:
item = resp['Item']
for key in value_dict.keys():
item[key] = value_dict[key]
try:
resp = table_obj.put_item(Item=item)
if resp:
if resp['ResponseMetadata']['HTTPStatusCode'] != 200:
return None
except:
return None
else:
return None
return True
# Constance for gamification
NEW_SQUARE = 10
NEW_POI = 20
# Constance for calculating of grid
LAT_SHIFT = Decimal("0.001")
LON_SHIFT = Decimal("0.0015")
NUM_LAT = 180 / LAT_SHIFT
NUM_LON = 360 / LON_SHIFT
# Function for calculating lower left corner of sqare as a Decimal
def calculate_sqare(lat, lon):
grid_lat = ((Decimal(str(lat)) + 90) // LAT_SHIFT) * LAT_SHIFT - 90
grid_lon = ((Decimal(str(lon)) + 180) // LON_SHIFT) * LON_SHIFT - 180
return (grid_lat, grid_lon)
# Function for calculating id of the square
def calculate_id(grid_lat, grid_lon):
return (grid_lat + 90) / LAT_SHIFT * NUM_LON + (grid_lon + 180) / LON_SHIFT
# Function for getting lat lon from square id
def calculate_grid(id):
lat = (id // NUM_LON) * LAT_SHIFT - 90
lon = (id % NUM_LON) * LON_SHIFT - 180
return (lat, lon)
# Dummy function, in future filtration of abuse usage
def filter(user, square_id):
return True
def lambda_handler(event, context):
'''Provide an event that contains the following keys:
- token: user token
- id: user id
- lat: lat
- lon: lon
- timestamp: event timestamp
'''
dyn_users = boto3.resource('dynamodb').Table('mapexplorer-users')
dyn_history = boto3.resource('dynamodb').Table('mapexplorer-history')
dyn_grid = boto3.resource('dynamodb').Table('mapexplorer-grid')
dyn_poi = boto3.resource('dynamodb').Table('mapexplorer-poi')
user = dynamo_request(dyn_users, {'id': event['id']})
if user:
if user['token'] == event['token']:
update_resp = dynamo_put(dyn_history, {'id': event['id'],
'lat': Decimal(str(event['lat'])),
'lon': Decimal(str(event['lon'])),
'timestamp': event['timestamp']})
if not update_resp:
raise Exception("Bad Request: Error adding new item to history")
grid_lat, grid_lon = calculate_sqare(event['lat'], event['lon'])
square_id = calculate_id(grid_lat, grid_lon)
if filter(user, square_id):
if square_id != user['lastLocation']:
# request and update grid table
grid_resp = dynamo_request(dyn_grid, {'squareId': square_id, 'userId': user['id']})
if grid_resp:
# user was here, update
update_resp = dynamo_update(dyn_grid, {'squareId': square_id,
'userId': user['id']}, {'heat': grid_resp['heat'] + 1})
if not update_resp:
raise Exception("Bad Request: Error updating square")
return {'xp_square': 0, 'xp_poi': 0}
else:
#new location add to grid, xp +10
put_resp = dynamo_put(dyn_grid, {'squareId': square_id, 'userId': user['id'], 'heat': 1})
if not put_resp:
raise Exception("Bad Request: Error adding new square")
resp = dyn_poi.query(KeyConditionExpression=Key('squareId').eq(square_id))
num_poi = 0
if resp.has_key('Items') and resp['Items']:
num_poi = len(resp['Items'])
coef = 1
if user['fitbitVerified']:
coef = 1.1
# Update XP in DynamoDB
new_xp = user['xp'] + int(NEW_SQUARE * coef) + NEW_POI * num_poi
update_xp = dynamo_update(dyn_users, {'id': user['id']}, {'xp': new_xp})
return {'xp_square': NEW_SQUARE, 'xp_poi': NEW_POI * num_poi, 'square_id': square_id}
else:
return {'xp_square': 0, 'xp_poi': 0}
else:
raise Exception("Unauthorized: Wrong token")
else:
raise Exception("Not Found: User not found")