Example #1
0
 def save_to_db(self) -> None:
     new_entry = Entity(self.datastore_key)
     new_entry.update({
         "prior_start_times":
         self._get_prior_start_times() + [self.started_at]
     })
     datastore_client.put(new_entry)
Example #2
0
def activity_entity_for_test(activity_id, with_photo=False):
    activity = Entity(ds_util.client.key('Activity', activity_id))
    activity['name'] = 'Activity ' + str(activity_id)
    activity['id'] = activity_id
    activity['description'] = 'Description: ' + str(activity_id)
    activity['distance'] = 10
    activity['moving_time'] = 200
    activity['elapsed_time'] = 100
    activity['total_elevation_gain'] = 300
    activity['start_date'] = datetime.datetime.fromtimestamp(1503517240)
    activity['athlete'] = Entity(ds_util.client.key('Athlete', 111))
    activity['athlete']['id'] = 111
    activity['athlete']['firstname'] = 'ActivityFirstName'
    activity['athlete']['lastname'] = 'ActivityLastName'
    activity['map'] = Entity(ds_util.client.key('Map', 111))
    activity['map']['summary_polyline'] = SUMMARY_POLYLINE
    if with_photo:
        activity['photos'] = {
            'primary': {
                'id': 1234,
                'unique_id': 'a807-23q4-23',
                'urls': {
                    '600': 'https://12341234.cloudfront.net/yw7_-ahaahahahahaha_E-576x768.jpg',
                    '100': 'https://12341234.cloudfront.net/yw7_-ahashdhaahashahah_E-96x128.jpg',
                },
            }
        }
    return activity
    def test_variable_meanings(self):
        from google.cloud.datastore_v1.proto import entity_pb2
        from google.cloud.datastore.entity import Entity
        from google.cloud.datastore.helpers import _new_value_pb

        entity = Entity()
        name = "quux"
        entity[name] = values = [1, 20, 300]
        meaning = 9
        entity._meanings[name] = ([None, meaning, None], values)
        entity_pb = self._call_fut(entity)

        # Construct the expected protobuf.
        expected_pb = entity_pb2.Entity()
        value_pb = _new_value_pb(expected_pb, name)
        value0 = value_pb.array_value.values.add()
        value0.integer_value = values[0]
        # The only array entry with a meaning is the middle one.
        value1 = value_pb.array_value.values.add()
        value1.integer_value = values[1]
        value1.meaning = meaning
        value2 = value_pb.array_value.values.add()
        value2.integer_value = values[2]

        self._compare_entity_proto(entity_pb, expected_pb)
Example #4
0
    def _setup_side_effects(
        self,
        create_client_mock,
        ds_util_client_get_mock,
        ds_util_client_put_mock,
        fcm_util_best_clients_mock,
        fcm_util_send_mock,
        measures,
    ):
        user = Entity(ds_util.client.key('User', 'someuser'))
        user['preferences'] = {'daily_weight_notif': True, 'units': 'METRIC'}
        service = Entity(
            ds_util.client.key('Service', 'withings', parent=user.key))
        service['credentials'] = {'refresh_token': 'validrefreshtoken'}
        event_entity = Entity(
            ds_util.client.key('SubscriptionEvent',
                               'Event',
                               parent=service.key))

        series = Entity(
            ds_util.client.key('Series', 'withings', parent=service.key))
        series['measures'] = measures

        # There are gets we need to account for.
        def get_side_effect(key):
            if key.name == 'someuser':
                return user
            elif key.name == 'withings':
                return series

        ds_util_client_get_mock.side_effect = get_side_effect

        return WeightTrendWorker(service, event_entity)
    def test_find_bot(self, mock_client_get):
        workspace_key = ds_util.client.key('SlackWorkspace',
                                           'enterprise_id-team_id')
        store = DatastoreInstallationStore(ds_util.client)

        bot_entity = Entity(
            ds_util.client.key('SlackBot', 'bot-latest', parent=workspace_key))
        bot_entity.update(
            Bot(
                app_id='app_id',
                bot_id='bot_id',
                bot_token='bot_token',
                bot_user_id='bot_user_id',
                installed_at=55.00,
            ).__dict__)
        mock_client_get.return_value = bot_entity
        found_bot = store.find_bot(enterprise_id='enterprise_id',
                                   team_id='team_id')
        self.assertIsNotNone(found_bot)
        self.assertIsInstance(found_bot, Bot)

        # Make sure we searched for the right key.
        key = mock_client_get.call_args[0][0]
        self.assertEqual(
            key,
            ds_util.client.key('SlackBot', 'bot-latest', parent=workspace_key))
    def test_find_installation(self, mock_client_get):
        workspace_key = ds_util.client.key('SlackWorkspace',
                                           'enterprise_id-team_id')
        store = DatastoreInstallationStore(ds_util.client)
        installation_entity = Entity(
            ds_util.client.key('SlackInstaller',
                               'installer-latest',
                               parent=workspace_key))
        installation_entity.update(
            Installation(
                app_id='app_id',
                enterprise_id='enterprise_id',
                team_id='team_id',
                user_id='user_id',
            ).__dict__)
        mock_client_get.return_value = installation_entity
        found_installation = store.find_installation(
            enterprise_id='enterprise_id', team_id='team_id')
        self.assertIsNotNone(found_installation)
        self.assertIsInstance(found_installation, Installation)

        # Make sure we searched for the right key.
        key = mock_client_get.call_args[0][0]
        self.assertEqual(
            key,
            ds_util.client.key('SlackInstaller',
                               'installer-latest',
                               parent=workspace_key),
        )
Example #7
0
    def test_process_event_task_discard_duplicate(
        self,
        ds_util_client_get_mock,
        ds_util_client_put_mock,
        ds_util_client_query_mock,
        ds_util_client_delete_multi_mock,
        withings_create_client_mock,
        withings_tasks_weight_trend_mock,
    ):
        user = Entity(ds_util.client.key('User', 'someuser'))
        user['preferences'] = {'daily_weight_notif': True}
        service = Entity(ds_util.client.key('Service', 'withings', parent=user.key))
        service['credentials'] = {'refresh_token': 'validrefreshtoken'}

        event_entity = Entity(
            ds_util.client.key('SubscriptionEvent', 'Event', parent=service.key)
        )

        # There are three gets we need to account for.
        def get_side_effect(key):
            if key.name == 'Event':
                return event_entity
            elif key.name == 'withings':
                return service
            elif key.name == 'someuser':
                return user

        ds_util_client_get_mock.side_effect = get_side_effect

        worker = EventsWorker(service, event_entity)
        worker.sync()

        ds_util_client_put_mock.assert_not_called()
        withings_tasks_weight_trend_mock.assert_not_called()
Example #8
0
 def test_mock_datastore_get(self, mock_datastore_service):
     entity = Entity()
     entity.update({
         'title': 'Example Title',
         'note_text': 'Example text',
         'user': '******',
         'last_modified_date': '',
         'created_date': ''
     })
     entities = list()
     entities.append(entity)
     mock_datastore_service.return_value.get.return_value = entities
     main.datastore = datastore.DatastoreService(
     )  # instantiate a new DatastoreService so it is replaced with mock
     r = self.app.post('/note/get',
                       data=json.dumps({'user': '******'}),
                       headers={'Content-Type': 'application/json'})
     assert r.status_code == 200
     assert r.json == {
         'matches': [{
             'title': 'Example Title',
             'note_text': 'Example text',
             'last_modified_date': ''
         }]
     }
    def test_variable_meanings(self):
        from google.cloud.proto.datastore.v1 import entity_pb2
        from google.cloud.datastore.entity import Entity
        from google.cloud.datastore.helpers import _new_value_pb

        entity = Entity()
        name = 'quux'
        entity[name] = values = [1, 20, 300]
        meaning = 9
        entity._meanings[name] = ([None, meaning, None], values)
        entity_pb = self._call_fut(entity)

        # Construct the expected protobuf.
        expected_pb = entity_pb2.Entity()
        value_pb = _new_value_pb(expected_pb, name)
        value0 = value_pb.array_value.values.add()
        value0.integer_value = values[0]
        # The only array entry with a meaning is the middle one.
        value1 = value_pb.array_value.values.add()
        value1.integer_value = values[1]
        value1.meaning = meaning
        value2 = value_pb.array_value.values.add()
        value2.integer_value = values[2]

        self._compareEntityProto(entity_pb, expected_pb)
    def test_installation_bot_to_entity_to_bot(self):
        installation = Installation(app_id='app_id', user_id='user_id')

        bot = installation.to_bot()
        entity = Entity()
        entity.update(bot.__dict__)
        from_entity = Bot(**entity)
        self.assertEqual(bot.__dict__, from_entity.__dict__)
Example #11
0
    def to_entity(cls, track, parent=None):
        props = copy.deepcopy(track)

        entity = Entity(
            ds_util.client.key('Track', track['url'], parent=parent),
            exclude_from_indexes=cls.EXCLUDE_FROM_INDEXES,
        )
        entity.update(props)
        return entity
Example #12
0
 def to_entity(cls, item):
     attributes = {
         'date':
         datetime.datetime.utcfromtimestamp(item['timestampGMT'] / 1000),
         'fat_ratio': item['bodyFat'],
         'weight': round(item['weight'] / 1000, 4),
     }
     entity = Entity(ds_util.client.key('Measure'))
     entity.update(attributes)
     return entity
Example #13
0
 def test_measures(self):
     measure_item = BODY_COMP['dateWeightList'][0]
     entity = GarminConverters.Measure.to_entity(measure_item)
     expected_entity = Entity(ds_util.client.key('Measure'))
     expected_entity.update({
         'date': datetime.datetime(2020, 3, 22, 1, 49),
         'fat_ratio': None,
         'weight': 59.4206,
     })
     self.assertEqual(entity.items(), expected_entity.items())
Example #14
0
    def test_one_year_ago(
        self,
        create_client_mock,
        ds_util_client_get_mock,
        ds_util_client_put_mock,
        get_now_mock,
        fcm_util_best_clients_mock,
        fcm_util_send_mock,
    ):
        now = datetime.datetime(2020,
                                9,
                                25,
                                7,
                                13,
                                tzinfo=datetime.timezone.utc)
        get_now_mock.return_value = now

        measures = []

        measures.insert(0, Entity())
        measures[0].update({'date': now, 'weight': 30})

        measures.insert(0, Entity())
        measures[0].update({
            'date':
            datetime.datetime(2020, 9, 24, 7, 13,
                              tzinfo=datetime.timezone.utc),
            'weight':
            35,
        })

        measures.insert(0, Entity())
        measures[0].update({
            'date':
            datetime.datetime(2019, 5, 18, 8, 12,
                              tzinfo=datetime.timezone.utc),
            'weight':
            60,
        })

        worker = self._setup_side_effects(
            create_client_mock,
            ds_util_client_get_mock,
            ds_util_client_put_mock,
            fcm_util_best_clients_mock,
            fcm_util_send_mock,
            measures,
        )
        worker.sync()

        self._assert_send(
            fcm_util_send_mock,
            'Down 30.0 kg from a year ago',
            'You were 60.0 kg on May 18, 2019',
        )
Example #15
0
def entity_from_protobuf(pb):
    """Factory method for creating an entity based on a protobuf.

    The protobuf should be one returned from the Cloud Datastore
    Protobuf API.

    :type pb: :class:`.entity_pb2.Entity`
    :param pb: The Protobuf representing the entity.

    :rtype: :class:`google.cloud.datastore.entity.Entity`
    :returns: The entity derived from the protobuf.
    """
    if isinstance(pb, entity_pb2.Entity):
        pb = pb._pb

    key = None
    if pb.HasField("key"):  # Message field (Key)
        key = key_from_protobuf(pb.key)

    entity_props = {}
    entity_meanings = {}
    exclude_from_indexes = []

    for prop_name, value_pb in pb.properties.items():
        value = _get_value_from_value_pb(value_pb)
        entity_props[prop_name] = value

        # Check if the property has an associated meaning.
        is_list = isinstance(value, list)
        meaning = _get_meaning(value_pb, is_list=is_list)
        if meaning is not None:
            entity_meanings[prop_name] = (meaning, value)

        # Check if ``value_pb`` was excluded from index. Lists need to be
        # special-cased and we require all ``exclude_from_indexes`` values
        # in a list agree.
        if is_list and len(value) > 0:
            exclude_values = set(value_pb.exclude_from_indexes
                                 for value_pb in value_pb.array_value.values)
            if len(exclude_values) != 1:
                raise ValueError("For an array_value, subvalues must either "
                                 "all be indexed or all excluded from "
                                 "indexes.")

            if exclude_values.pop():
                exclude_from_indexes.append(prop_name)
        else:
            if value_pb.exclude_from_indexes:
                exclude_from_indexes.append(prop_name)

    entity = Entity(key=key, exclude_from_indexes=exclude_from_indexes)
    entity.update(entity_props)
    entity._meanings.update(entity_meanings)
    return entity
 def test_bot_to_entity_to_bot(self):
     bot = Bot(
         app_id='app_id',
         bot_id='bot_id',
         bot_token='bot_token',
         bot_user_id='bot_user_id',
         installed_at=55.00,
     )
     entity = Entity()
     entity.update(bot.__dict__)
     from_entity = Bot(**entity)
     self.assertEqual(bot.__dict__, from_entity.__dict__)
Example #17
0
 def to_entity(cls, measure, parent=None):
     date = datetime.datetime.strptime(
         measure['date'] + ' ' + measure['time'], '%Y-%m-%d %H:%M:%S')
     entity = Entity(
         ds_util.client.key('Measure', date.strftime('%s'), parent=parent))
     entity.update(
         dict(
             id=measure['logId'],
             date=date,
             weight=measure['weight'],
             fat_ratio=measure['fat'],
         ))
     return entity
Example #18
0
def entity_from_protobuf(pb):
    """Factory method for creating an entity based on a protobuf.

    The protobuf should be one returned from the Cloud Datastore
    Protobuf API.

    :type pb: :class:`google.cloud.datastore._generated.entity_pb2.Entity`
    :param pb: The Protobuf representing the entity.

    :rtype: :class:`google.cloud.datastore.entity.Entity`
    :returns: The entity derived from the protobuf.
    """
    key = None
    if pb.HasField('key'):  # Message field (Key)
        key = key_from_protobuf(pb.key)

    entity_props = {}
    entity_meanings = {}
    exclude_from_indexes = []

    for prop_name, value_pb in _property_tuples(pb):
        value = _get_value_from_value_pb(value_pb)
        entity_props[prop_name] = value

        # Check if the property has an associated meaning.
        is_list = isinstance(value, list)
        meaning = _get_meaning(value_pb, is_list=is_list)
        if meaning is not None:
            entity_meanings[prop_name] = (meaning, value)

        # Check if ``value_pb`` was excluded from index. Lists need to be
        # special-cased and we require all ``exclude_from_indexes`` values
        # in a list agree.
        if is_list:
            exclude_values = set(value_pb.exclude_from_indexes
                                 for value_pb in value_pb.array_value.values)
            if len(exclude_values) != 1:
                raise ValueError('For an array_value, subvalues must either '
                                 'all be indexed or all excluded from '
                                 'indexes.')

            if exclude_values.pop():
                exclude_from_indexes.append(prop_name)
        else:
            if value_pb.exclude_from_indexes:
                exclude_from_indexes.append(prop_name)

    entity = Entity(key=key, exclude_from_indexes=exclude_from_indexes)
    entity.update(entity_props)
    entity._meanings.update(entity_meanings)
    return entity
Example #19
0
    def test_process_link_shared_called(self, slack_process_link_shared_mock):
        event_entity = Entity(
            ds_util.client.key('SubscriptionEvent', 'slack-E232eq2ee')
        )
        event_entity.update(LINK_SHARED_EVENT)

        self.client.post(
            '/tasks/event',
            data=task_util.task_body_for_test(event=event_entity),
        )
        # It doesn't matter what code gets returned, since the method returns
        # whatever _process_link_shared returns, which is a mock. Only test
        # that _process_link_shared is called.
        slack_process_link_shared_mock.assert_called_once()
Example #20
0
    def test_process_link_shared(self, mock_create_unfurls, mock_slack_client):
        mock_create_unfurls.return_value = {'http://example.com': 'unfurl'}

        event_entity = Entity(
            ds_util.client.key('SubscriptionEvent', 'slack-E232eq2ee')
        )
        event_entity.update(LINK_SHARED_EVENT)

        r = self.client.post(
            '/tasks/event',
            data=task_util.task_body_for_test(event=event_entity),
        )

        mock_slack_client.assert_called_once()
        responses.assertResponse(self, responses.OK, r)
Example #21
0
def track_finished_for_test() -> Entity:
    track = Entity(ds_util.client.key('Track', 10285651))
    track.update(
        {
            "info": {
                "gcAvatar": "https://s3.amazonaws.com/garmin-connect-prod/profile_images/avatar.png",
                "session": {
                    "end": "2021-04-11T20:28:36.000Z",
                    "position": {
                        "lat": 37.77,
                        "locationName": "San Francisco",
                        "lon": -122.44,
                    },
                    "publisher": {
                        "connectUserProfileId": 123456,
                        "identifier": "PUBLISHERIDPUBLISHERID",
                        "nickname": "Joe LaPenna",
                        "trackerId": "UA69B7XL",
                        "type": "WEARABLE",
                    },
                    "publisherState": "ACTIVE",
                    "sessionId": "session-session",
                    "sessionName": "04/11/21",
                    "start": "2021-04-11T15:00:09.000Z",
                    "subscriber": {
                        "identifier": "*****@*****.**",
                        "type": "EMAIL",
                    },
                    "subscriberState": "ACTIVE",
                    "token": "1618153228",
                    "url": "https://livetrack.garmin.com/session/session-session/token/TOKENTOKEN",
                    "userDisplayName": "Joe LaPenna",
                    "viewable": "2021-04-11T20:28:36.000Z",
                },
                "shortened": False,
                "unitId": 3996815102,
                "viewable": False,
            },
            "start": datetime.datetime(
                2021, 4, 11, 15, 00, tzinfo=datetime.timezone.utc
            ),
            "end": datetime.datetime(2021, 4, 11, 20, 28, tzinfo=datetime.timezone.utc),
            "status": 4,  # FINISHED
            "url": "https://livetrack.garmin.com/session/session-session/token/TOKENTOKEN",
            "url_info": {"session": "session-session", "token": "TOKENTOKEN"},
        }
    )
    return track
    def test_entity(self):
        from google.cloud.datastore.entity import Entity

        entity = Entity()
        name, value = self._call_fut(entity)
        self.assertEqual(name, 'entity_value')
        self.assertIs(value, entity)
    def test_empty(self):
        from google.cloud.proto.datastore.v1 import entity_pb2
        from google.cloud.datastore.entity import Entity

        entity = Entity()
        entity_pb = self._call_fut(entity)
        self._compareEntityProto(entity_pb, entity_pb2.Entity())
Example #24
0
    def test_put_multi_w_single_empty_entity(self):
        # https://github.com/GoogleCloudPlatform/google-cloud-python/issues/649
        from google.cloud.datastore.entity import Entity

        creds = object()
        client = self._makeOne(credentials=creds)
        self.assertRaises(ValueError, client.put_multi, Entity())
Example #25
0
def put_attendance(meeting, attendance):
    exkeys = [
        'name1', 'name2', 'group1', 'group2', 'email', 'attendance1',
        'attendance2', 'anonymous', 'message', 'zip1', 'zip2', 'address',
        'tel', 'fax', 'office', 'officetel', 'created', 'updated'
    ]
    key = None
    if not attendance.id:
        key = datastore_client.key('meeting', meeting.id, 'attendance')
    else:
        key = datastore_client.key('meeting', meeting.id, 'attendance',
                                   attendance.id)
    entity = Entity(key=key, exclude_from_indexes=exkeys)
    entity['name1'] = attendance.name1
    entity['name2'] = attendance.name2
    entity['group1'] = attendance.group1
    entity['group2'] = attendance.group2
    entity['email'] = attendance.email
    entity['attendance1'] = attendance.attendance1
    entity['attendance2'] = attendance.attendance2
    entity['anonymous'] = attendance.anonymous
    entity['message'] = attendance.message
    entity['zip1'] = attendance.zip1
    entity['zip2'] = attendance.zip2
    entity['address'] = attendance.address
    entity['tel'] = attendance.tel
    entity['fax'] = attendance.fax
    entity['office'] = attendance.office
    entity['officetel'] = attendance.officetel
    entity['created'] = attendance.created
    entity['updated'] = attendance.updated
    datastore_client.put(entity)
Example #26
0
 def issue(self, *args, **kwargs) -> str:
     state = str(uuid4())
     entity = Entity(self.client.key('SlackStateStore', state))
     entity['body'] = str(time.time())
     response = self.client.put(entity)
     self.logger.debug(f"DS put response: {response}")
     return state
Example #27
0
 def from_uid(cls, uid):
     key = ds_util.client.key('User', uid)
     user = ds_util.client.get(key)
     if not user:
         user = Entity(key)
     User._set_defaults(user)
     return user
    def test_empty(self):
        from google.cloud.datastore_v1.types import entity as entity_pb2
        from google.cloud.datastore.entity import Entity

        entity = Entity()
        entity_pb = self._call_fut(entity)
        self._compare_entity_proto(entity_pb, entity_pb2.Entity())
Example #29
0
 def to_entity(cls, measures, parent):
     series = Entity(
         ds_util.client.key('Series', parent.name, parent=parent))
     series['measures'] = [
         Measure.to_entity(measure, parent) for measure in measures
     ]
     return series
    def test_dict_to_entity_recursive(self):
        from google.cloud.datastore_v1.types import entity as entity_pb2
        from google.cloud.datastore.entity import Entity

        entity = Entity()
        entity["a"] = {"b": {"c": {"d": 1.25}, "e": True}, "f": 10}
        entity_pb = self._call_fut(entity)

        b_entity_pb = entity_pb2.Entity(
            properties={
                "c":
                entity_pb2.Value(entity_value=entity_pb2.Entity(
                    properties={"d": entity_pb2.Value(double_value=1.25)})),
                "e":
                entity_pb2.Value(boolean_value=True),
            })
        expected_pb = entity_pb2.Entity(
            properties={
                "a":
                entity_pb2.Value(entity_value=entity_pb2.Entity(
                    properties={
                        "b": entity_pb2.Value(entity_value=b_entity_pb),
                        "f": entity_pb2.Value(integer_value=10),
                    }))
            })
        self.assertEqual(entity_pb, expected_pb)
Example #31
0
        def perform_insert(entities):
            results = []
            rpc = transaction._rpc(self.connection.alias)
            must_handle_unique = has_active_unique_constraints(self.model)

            for primary, descendents in entities:
                if primary.key.is_partial:
                    primary.key = primary.key.completed_key(rpc._generate_id())

                # thanks to cloud firestore in datastore mode strong consistency
                # we can query for the relevant entities to enforce uniqueness
                if must_handle_unique:
                    perform_unique_checks(
                        self.model,
                        rpc,
                        primary,
                        test_fn=lambda stored: stored and len(stored) > 0)

                rpc.put(primary)
                new_key = primary.key

                if descendents:
                    for i, descendent in enumerate(descendents):
                        key = rpc.key(descendent.kind,
                                      descendent.key.id_or_name,
                                      parent=new_key)
                        descendents[i] = Entity(key)
                        descendents[i].update(descendent)

                    for descendent in descendents:
                        rpc.put(descendent)

                results.append(new_key)
            return results
Example #32
0
            def perform_insert():
                """
                    Inserts result, and any descendents with their ancestor
                    value set
                """
                client = transaction._rpc(self.connection.alias)

                def test_fn(stored):
                    return stored and len(
                        stored) == 1 and stored[0].key != result.key

                if has_active_unique_constraints(self.model):
                    perform_unique_checks(self.model, client, primary, test_fn)

                inserted_key = client.put(result)
                self.results.append((result, None))

                if descendents:
                    for i, descendent in enumerate(descendents):
                        descendents[i] = Entity(
                            client.key(
                                descendent.kind,
                                descendent.key.name
                                if descendent.key.id is None else
                                descendent.key.id,
                                parent=inserted_key,
                            ))
                        descendents[i].update(descendent)
                    client.put_multi(descendents)
    def test_meaning_with_change(self):
        from google.cloud.datastore_v1.proto import entity_pb2
        from google.cloud.datastore.entity import Entity
        from google.cloud.datastore.helpers import _new_value_pb

        entity = Entity()
        name = "foo"
        entity[name] = value = 42
        entity._meanings[name] = (9, 1337)
        entity_pb = self._call_fut(entity)

        expected_pb = entity_pb2.Entity()
        value_pb = _new_value_pb(expected_pb, name)
        value_pb.integer_value = value
        # NOTE: No meaning is used since the value differs from the
        #       value stored.
        self._compare_entity_proto(entity_pb, expected_pb)