Пример #1
0
    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) ]})
Пример #2
0
    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)]})
Пример #3
0
    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()
Пример #4
0
    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()))
Пример #5
0
    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)
Пример #6
0
    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()
Пример #7
0
    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)
Пример #8
0
    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]})
Пример #9
0
    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)
Пример #10
0
    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')
Пример #11
0
    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})
Пример #12
0
    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]})
Пример #13
0
    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})
Пример #14
0
    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})
Пример #15
0
    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})
Пример #16
0
    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})
Пример #17
0
    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)
Пример #18
0
    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')
Пример #19
0
    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')
Пример #20
0
    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')
Пример #21
0
    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')
Пример #22
0
    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) ]})
Пример #23
0
    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)
Пример #24
0
    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()