def post(self): if self.request.get('_put'): self.put() return name = self.request.get('name') member_ids = self.request.get_all('member_uuid') public = self.request.get('public') user = api.get_user(self.request) if not user: api.write_error(self.response, 400, 'Unknown or missing user') return group = Group(uuid=str(uuid.uuid4())) group.admins.append(user.key) group.members.append(user.key) group.name = name if 'public' in self.request.params and not public == '': group.public = public.lower() in ("yes", "true", "t", "1", "on") for member_id in member_ids: member = User.query(User.uuid == member_id).get() if member: group.members.append(member.key) group.put() if group.public: api.search.update_public_index(group) else: api.search.update_private_index(group, user.uuid) api.write_message(self.response, 'success', extra={'groups' : [ get_group_json(group) ]})
def post(self): if self.request.get('_put'): self.put() return name = self.request.get('name') email = self.request.get('email') push_token = self.request.get('token') device_type = self.request.get('type') if not push_token or not device_type: api.write_error(self.response, 400, 'Missing required parameter, token or type') return user = User(uuid=str(uuid.uuid4()), auth=str(uuid.uuid4())) if name: user.name = name update_gender(user) if email: user.devices.append(Device(device_type='EMAIL', data=email)) user.devices.append(Device(device_type=device_type.upper(), data=push_token)) user.put() update_user_cards(user) api.search.update_public_index(user) api.write_message(self.response, 'success', extra={'users' : [get_user_json(user, public=False)]})
def get(self): uuid = self.request.get('uuid') size = self.request.get('size') size = int(size) if size else config.PROFILE_ICON_SIZE if not uuid: api.write_error(self.response, 400, 'Unknown or missing user') return filename = config.PROFILE_BUCKET + uuid image = images.Image(blob_key=blobstore.create_gs_key('/gs' + filename)) image.resize(width=size, height=size, crop_to_fit=True, allow_stretch=False) try: png_data = StringIO.StringIO(image.execute_transforms(output_encoding=images.PNG)) except: self.redirect(config.DEFAULT_PHOTO_URL) return im = Image.open(png_data) bigsize = (im.size[0] * 3, im.size[1] * 3) mask = Image.new('L', bigsize, 0) draw = ImageDraw.Draw(mask) draw.ellipse((0, 0) + bigsize, fill=255) mask = mask.resize(im.size, Image.ANTIALIAS) im.putalpha(mask) output = StringIO.StringIO() im.save(output, 'PNG') self.response.headers['Content-Type'] = 'image/png' self.response.headers['Cache-Control'] = 'public,max-age=%d' % (config.MEDIA_MAX_AGE) self.response.out.write(output.getvalue()) output.close()
def post(self): time_millis = self.request.get('time') data = self.request.get('data') tags = self.request.get('tags') try: referer = self.request.headers['Referer'] except: referer = '' user = api.get_user(self.request) if not user and referer.find('/poll') < 0: api.write_error(self.response, 400, 'Unknown or missing user') return if not tags or not time_millis: api.write_error(self.response, 400, 'Missing required parameter.') return tags = tags.lower().split(',') time = api.get_time_from_millis(time_millis) if user: event = Event(parent=user.key, tags=tags, time=time, data=data) else: event = Event(tags=tags, time=time, data=data) event.put_async() api.write_message( self.response, 'Successfully added event %s' % (event.key.urlsafe()))
def get(self): tags = self.request.get('tags') start_millis = self.request.get('start_time') end_millis = self.request.get('end_time') chart_type = self.request.get('type') tz_offset = self.request.get('tz_offset') debug = self.request.get('debug') if not tags: api.write_error(self.response, 400, 'Missing required parameter, tags') return tags = tags.lower().split(',') query = get_user_event_query(api.get_user(self.request), tags, start_millis, end_millis) results = {} events = [] xdata = [] ydata = [] for event in query: if debug: events.append(get_event_json(event)) try: if chart_type and chart_type == 'time': measurement = json.loads(event.data) xdata.append(api.get_local_time(event.time, tz_offset)) ydata.append(int(measurement['value'])) else: results[event.data] += 1 except: results[event.data] = 1 if debug: api.write_message(self.response, 'success', extra={'events': events}) return if query.count() == 0: api.write_error(self.response, 404, 'Not enough data points for chart.') return if chart_type and chart_type == 'time': # Reverse the data as we query events in descending order of time xdata.reverse() ydata.reverse() show_vertical_bars(self.response, xdata, ydata) else: show_horizontal_bars(self.response, results)
def get(self): if self.request.get('_delete'): self.delete() return recording_id = self.request.get('id') start = self.request.get('start') end = self.request.get('end') flip = self.request.get('flip') grid = self.request.get('grid') flag_smooth = self.request.get('smooth') if not recording_id: api.write_error(self.response, 400, 'Missing required parameter: id') return filename = config.RECORDINGS_BUCKET + recording_id data = read(filename) if start and end: start_index = int(start) * config.SAMPLES_PER_SEC end_index = int(end) * config.SAMPLES_PER_SEC data = data[start_index:end_index] elif start: start_index = int(start) * config.SAMPLES_PER_SEC end_index = (int(start) + 10) * config.SAMPLES_PER_SEC data = data[start_index:end_index] if flip: data = [(255 - value) for value in data] if flag_smooth: data = smooth(data) figure = get_figure(data, grid) output = StringIO.StringIO() figure.savefig(output, dpi=100, orientation='landscape', format='png', transparent=True, frameon=False, bbox_inches='tight', pad_inches=0) self.response.headers['Content-Type'] = 'image/png' self.response.out.write(output.getvalue()) output.close()
def put(self): card_id = self.request.get('card_id') tag = self.request.get('tag') tags = self.request.get('tags') text = self.request.get('text') user = api.get_user(self.request) if not user: api.write_error(self.response, 400, 'Unknown or missing user') return if not card_id: api.write_error(self.response, 400, 'Missing required parameter') return if not tag and not tags: api.write_error(self.response, 400, 'Missing parameter to update') return card = ndb.Key(urlsafe=card_id).get() if not card: api.write_error(self.response, 404, 'Card not found') return if tags: card.tags = tags.lower().split(',') elif tag and not tag.lower() in card.tags: card.tags.append(tag.lower()) card.text = text if text else card.text card.put() api.write_message(self.response, 'Successfully updated the card') api.search.update_private_index(card, user.uuid)
def get(self): uuid = self.request.get('uuid') user = api.get_user(self.request) if not user: api.write_error(self.response, 403, 'Unknown or missing user') return json = None if uuid: other = User.query(User.uuid == uuid).get() if other: json = get_user_json(other) if not json: json = get_user_json(user, public=False) api.write_message(self.response, 'success', extra={'users' : [json]})
def get(self): recording_id = self.request.get('id') if not recording_id: api.write_error(self.response, 400, 'Missing required parameter: id') return filename = config.RECORDINGS_BUCKET + recording_id gcs_file = gcs.open(filename) data = gcs_file.read() gcs_file.close() recording = Recording.query(Recording.uuid == recording_id).get() filename = str(' '.join(recording.tags)) + '.raw' self.response.headers['Content-Type'] = 'application/binary' self.response.headers[ 'Content-Disposition'] = 'attachment; filename="%s"' % (filename) self.response.out.write(data)
def delete(self): recording_id = self.request.get('id') if not recording_id: api.write_error(self.response, 400, 'Missing required parameter: id') return filename = config.RECORDINGS_BUCKET + recording_id try: gcs.delete(filename) except: api.write_error(self.response, 500, 'Unable to delete file') return recording = Recording.query(Recording.uuid == recording_id).get() recording.key.delete() api.write_message(self.response, 'success')
def get(self): uuid = self.request.get('group_uuid') user = api.get_user(self.request) if not user: api.write_error(self.response, 403, 'Unknown or missing user') return if uuid: query = Group.query(Group.uuid == uuid) else: query = Group.query(ndb.OR(Group.members == user.key, Group.admins == user.key)).order(-Group.update_time) groups = [] for group in query: if user.key in group.members or user.key in group.admins: groups.append(get_group_json(group)) api.write_message(self.response, 'success', extra={'groups' : groups})
def put(self): name = self.request.get('name') email = self.request.get('email') push_token = self.request.get('token') device_type = self.request.get('type') features = self.request.get_all('feature') user = api.get_user(self.request) if not user: api.write_error(self.response, 403, 'Unknown or missing user') return if name: user.name = name token_updated = False email_updated = False for device in user.devices: if email and device.device_type == 'EMAIL': device.data = email email_updated = True elif push_token and device_type and device.device_type == device_type: device.data = push_token token_updated = True if not token_updated and push_token and device_type: user.devices.append(Device(device_type=device_type.upper(), data=push_token)) if not email_updated and email: user.devices.append(Device(device_type='EMAIL', data=email)) for feature in features: update_feature(user, feature) user.last_location = api.get_geo_point(self.request) update_user_cards(user) user.put() api.search.update_public_index(user) json = get_user_json(user, public=False) api.write_message(self.response, 'Updated user', extra={'users' : [json]})
def get(self): start_millis = self.request.get('start_time') end_millis = self.request.get('end_time') tags = self.request.get('tags') user = api.get_user(self.request) if not user: api.write_error(self.response, 400, 'Unknown or missing user') return if not tags: api.write_error(self.response, 400, 'Missing required parameter, tags.') return tags = tags.lower().split(',') query = get_user_event_query(user, tags, start_millis, end_millis) events = [] for event in query: events.append(get_event_json(event)) api.write_message(self.response, 'success', extra={'events': events})
def get(self): uuid = self.request.get('group_uuid') user = api.get_user(self.request) if not user: api.write_error(self.response, 403, 'Unknown or missing user') return group = None if uuid: group = Group.query(Group.uuid == uuid).get() if group: query = Message.query(ancestor=group.key).order(-Message.create_time) else: query = Message.query(Message.sender == user.key).order(-Message.create_time) messages = [] for message in query: messages.append(get_message_json(message)) api.write_message(self.response, 'success', extra={'messages' : messages})
def get(self): query = self.request.get('q') location = None if self.request.get('nearby'): location = api.get_geo_point(self.request) user = api.get_user(self.request) if not user: api.write_error(self.response, 403, 'Unknown or missing user') return object_keys = search_objects(query, location, user.uuid) results = [] result = ndb.get_multi_async(object_keys) ndb.Future.wait_all(result) for handle in result: data = {} try: obj = handle.get_result() if isinstance(obj, Message) and api.is_user_allowed_message_view( user, obj): data['message'] = get_message_json(obj) elif isinstance(obj, Group) and api.is_user_allowed_group_view( user, obj): data['group'] = get_group_json(obj) elif isinstance(obj, User): data['user'] = get_user_json(obj) elif isinstance(obj, Card): data['card'] = get_card_json(obj) except: pass if data: results.append(data) api.write_message(self.response, 'success', extra={'results': results})
def get(self): tags = self.request.get('tags') public = self.request.get('public') user = api.get_user(self.request) if not user: api.write_error(self.response, 400, 'Unknown or missing user') return if public: user = User.query(User.uuid == config.SUPER_USER_UUID).get() cards = [] if tags: tags = tags.lower().split(',') query = Card.query(Card.tags.IN(tags), ancestor=user.key).order(-Card.create_time) else: query = Card.query(ancestor=user.key).order(-Card.create_time) for card in query: cards.append(get_card_json(card)) api.write_message(self.response, 'success', extra={'cards': cards})
def post(self): if self.request.get('_put'): self.put() return if self.request.get('_delete'): self.delete() return text = self.request.get('text') tags = self.request.get('tags') user = api.get_user(self.request) if not user: api.write_error(self.response, 400, 'Unknown or missing user') return if not tags or not text: api.write_error(self.response, 400, 'Missing required parameter') return content = { 'tags': tags.lower().split(','), 'text': text, 'priority': self.request.get('priority'), 'image': self.request.get('image'), 'icon': self.request.get('icon'), 'url': self.request.get('url'), 'expire_time': self.request.get('expire_time'), 'options': self.request.get_all('option') } card = make_card(content, user) card.put() api.write_message(self.response, 'Successfully added card %s' % (card.key.urlsafe())) api.search.update_private_index(card, user.uuid)
def post(self): uuid = self.request.get('group_uuid') text = self.request.get('text') if not uuid: api.write_error(self.response, 400, 'Missing required parameter, group_uuid') return user = api.get_user(self.request) if not user: api.write_error(self.response, 403, 'Unknown or missing user') return group = Group.query(Group.uuid == uuid).get() if not group: api.write_error(self.response, 404, 'Unknown or missing group for ') return message = Message(parent=group.key, sender=user.key, text=text) message.put() if group.public: api.search.update_public_index(message) else: api.search.update_private_index(message, user.uuid) gcm = [] for member in group.members: if member == user.key: continue device = get_user_device(member.get()) if device and device.device_type == 'APPLE': gcm.append(device.data) elif device and device.device_type == 'GOOGLE': gcm.append(device.data) elif device and device.device_type == 'EMAIL': api.email(device.data, get_message_json(message)) if gcm: api.gcm(gcm, {'message': get_message_json(message), 'group_uuid': group.uuid}) # Update the group update date group.put_async() api.write_message(self.response, 'Successfully added message')
def post(self): if self.request.get('_delete'): self.delete() return tags = clean_tags(self.request.get('tags')) if not tags: api.write_error(self.response, 400, 'Missing required parameter: tags') return tags.append(api.get_geo_name(self.request)) try: uploaded_file = self.request.POST['file'] if not uploaded_file.type: api.write_error(self.response, 400, 'Missing content type') return except: uploaded_file = None if uploaded_file == None: api.write_error(self.response, 400, 'Missing content') return recording_id = str(uuid.uuid4()) filename = config.RECORDINGS_BUCKET + recording_id gcs_file = gcs.open(filename, mode='w', content_type=uploaded_file.type) gcs_file.write(uploaded_file.file.read()) gcs_file.close() stat = gcs.stat(filename) recording = Recording(uuid=recording_id, tags=tags, duration=stat.st_size / config.SAMPLES_PER_SEC) recording.put_async() api.write_message(self.response, 'success')
def delete(self): card_id = self.request.get('card_id') user = api.get_user(self.request) if not user: api.write_error(self.response, 400, 'Unknown or missing user') return card = ndb.Key(urlsafe=card_id).get() if not card: api.write_error(self.response, 404, 'Card not found') return if not card.key.parent() == user.key: api.write_error(self.response, 403, 'Only owner of the card can delete it.') return api.search.delete_from_indices(card, user.uuid) card.key.delete_async() api.write_message(self.response, 'success')
def post(self): user = api.get_user(self.request) if not user: api.write_error(self.response, 400, 'Unknown or missing user') return try: uploaded_file = self.request.POST['file'] if not uploaded_file.type: api.write_error(self.response, 400, 'Missing content type') return except: uploaded_file = None if uploaded_file == None: api.write_error(self.response, 400, 'Missing content') return filename = config.PROFILE_BUCKET + user.uuid gcs_file = gcs.open(filename, mode='w', content_type=uploaded_file.type, options={'x-goog-acl': 'public-read'}) gcs_file.write(uploaded_file.file.read()) gcs_file.close(); api.write_message(self.response, 'success')
def put(self): uuid = self.request.get('group_uuid') name = self.request.get('name') admin_ids = self.request.get_all('admin_uuid') member_ids = self.request.get_all('member_uuid') public = self.request.get('public') if not uuid: api.write_error(self.response, 400, 'Missing required parameter, group_uuid') return user = api.get_user(self.request) if not user: api.write_error(self.response, 403, 'Unknown or missing user') return group = Group.query(Group.uuid == uuid).get() if not group: api.write_error(self.response, 404, 'Unknown or missing group') return if not user.key in group.admins: api.write_error(self.response, 403, 'User not allowed to update group') return if name: group.name = name if 'public' in self.request.params and not public == '': group.public = public.lower() in ("yes", "true", "t", "1", "on") for admin_id in admin_ids: remove_user = False if admin_id and admin_id[0] == '-': remove_user = True admin_id = admin_id[1:] admin = User.query(User.uuid == admin_id).get() if admin: if remove_user and admin.key in group.admins: if len(group.admins) > 1: group.admins.remove(admin.key) else: api.write_error(self.response, 403, 'Cannot remove last admin') return elif not admin.key in group.admins: group.admins.append(admin.key) else: logging.warn('Unknown user %s' % (admin_id)) for member_id in member_ids: remove_user = False if member_id and member_id[0] == '-': remove_user = True member_id = member_id[1:] member = User.query(User.uuid == member_id).get() if member: if remove_user and member.key in group.members: group.members.remove(member.key) elif not member.key in group.members: group.members.append(member.key) else: logging.warn('Unknown user %s' % (member_id)) group.put() if group.public: api.search.update_public_index(group) else: api.search.update_private_index(group, user.uuid) api.write_message(self.response, 'Updated group', extra={'groups' : [ get_group_json(group) ]})
def post(self): email = self.request.get('email') push_token = self.request.get('token') device_type = self.request.get('type') user_uuid = self.request.get('uuid') code = self.request.get('code') if user_uuid and code: code = int(code) user = User.query(User.uuid == user_uuid).get() if not user or not user.recovery: api.write_error(self.response, 404, 'User not found') return if not user.recovery.code == code: api.write_error(self.response, 403, 'Invalid recovery code') return if (datetime.datetime.now() - user.recovery.time).seconds > (15 * 60): api.write_error(self.response, 403, 'Old recovery code') return user.auth = str(uuid.uuid4()) user.put() api.write_message(self.response, 'success', extra={'users' : [get_user_json(user, public=False)]}) return users = User.query(User.devices.data == email) if not users or users.count(limit=1) < 1: api.write_error(self.response, 404, 'User not found') return extra = {} push_token_found = False; first_user = None for user in users: if not user or not user.devices: continue if not first_user: first_user = user for device in user.devices: if not device.device_type in ['GOOGLE', 'APPLE', 'AMAZON']: continue if device.device_type == device_type and device.data == push_token: push_token_found = True if device.device_type == 'GOOGLE': user.auth = str(uuid.uuid4()) user.put() user_json = get_user_json(user, public=False) user_json['cards'] = [] api.gcm([push_token], {'user': user_json}) elif device.device_type == 'APPLE': # Until we can deliver data to iOS app directly, use email for them push_token_found = False if not push_token_found and first_user: # Is this correct to pick first user? if not first_user.recovery: first_user.recovery = Recovery() first_user.recovery.code = random.randint(1000, 9999) api.email(email, config.EMAIL_RECOVERY_SUBJECT, config.EMAIL_RECOVERY_BODY % (first_user.recovery.code)) first_user.put() extra = {'users' : [get_user_json(first_user)]} api.write_message(self.response, 'success', extra=extra)
def get(self): uuid = self.request.get('group_uuid') size = self.request.get('size') size = int(size) if size else config.PROFILE_ICON_SIZE if not uuid: api.write_error(self.response, 400, 'Unknown or missing user') return group = Group.query(Group.uuid == uuid).get() if not group: api.write_error(self.response, 404, 'Unknown or missing group') return images = [] margin = int(size * 4 / 100) margin = margin if margin else 2 positions = [(0, 0), (size / 2 + margin, 0), (size / 2 + margin, size / 2 + margin)] for member_key in group.members: if len(images) == len(positions): break member = member_key.get() if not member: continue filename = config.PROFILE_BUCKET + member.uuid image = ImageApi.Image(blob_key=blobstore.create_gs_key('/gs' + filename)) try: gcs_file = gcs.open(filename, 'r') images.append(image) gcs_file.close() except: pass if len(images) == 0: api.write_error(self.response, 404, 'No group photo available') return elif len(images) == 1: sizes = [(size, size)] elif len(images) == 2: sizes = [(size / 2, size), (size / 2, size)] else: sizes = [(size / 2, size), (size / 2, size / 2), (size / 2, size / 2)] new_im = Image.new('RGB', (size, size), color=(255, 255, 255, 0)) for image in images: (width, height) = sizes.pop(0) image.resize(width=width, height=height, crop_to_fit=True, allow_stretch=False) im = Image.open(StringIO.StringIO(image.execute_transforms(output_encoding=ImageApi.PNG))) new_im.paste(im, positions.pop(0)) bigsize = (new_im.size[0] * 3, new_im.size[1] * 3) mask = Image.new('L', bigsize, 0) draw = ImageDraw.Draw(mask) draw.ellipse((0, 0) + bigsize, fill=255) mask = mask.resize(new_im.size, Image.ANTIALIAS) new_im.putalpha(mask) output = StringIO.StringIO() new_im.save(output, 'PNG') self.response.headers['Content-Type'] = 'image/png' self.response.headers['Cache-Control'] = 'public,max-age=%d' % (config.MEDIA_MAX_AGE) self.response.out.write(output.getvalue()) output.close()