def test_get_initial_from_dataset(self):

        dataset_json = TEST_DATASET_FULL_GENERIC_FORM

        form = ObservationForm(self.app, dataset_json)

        initial = form.get_initial_from_dataset(dataset_json['dataset'])

        taxonomic_reference_uuid = dataset_json['dataset']['observation_form'][
            'taxonomic_reference']
        temporal_reference_uuid = dataset_json['dataset']['observation_form'][
            'temporal_reference']
        geographic_reference_uuid = dataset_json['dataset'][
            'observation_form']['geographic_reference']

        for key, value in initial.items():

            self.assertIn(key, dataset_json['dataset']['reported_values'])

            reported_value = dataset_json['dataset']['reported_values'][key]

            if key == taxonomic_reference_uuid:
                # check the taxon
                self.assertEqual(value.taxon_source,
                                 reported_value['taxon_source'])
                self.assertEqual(value.taxon_latname,
                                 reported_value['taxon_latname'])
                self.assertEqual(value.name_uuid, reported_value['name_uuid'])
            elif key == temporal_reference_uuid:
                self.assertEqual(value, datetime_from_cron(reported_value))
            else:
                self.assertEqual(value, reported_value)
    def compress(self, data_list):

        """
        Return a single value for the given list of values. The values can be
        assumed to be valid.

        For example, if this MultiValueField was instantiated with
        fields=(DateField(), TimeField()), this might return a datetime
        object created by combining the date and time in data_list.
        """

        if data_list:
            cron = json.loads(data_list[1])
            return datetime_from_cron(cron)

        return None
示例#3
0
    def get_initial_from_dataset(self, dataset_json):

        initial = {}

        taxonomic_reference_uuid = dataset_json['observation_form'][
            'taxonomic_reference']
        temporal_reference_uuid = dataset_json['observation_form'][
            'temporal_reference']
        geographic_reference_uuid = dataset_json['observation_form'][
            'geographic_reference']

        for key, value in dataset_json['reported_values'].items():

            if key == taxonomic_reference_uuid:
                initial[key] = LazyAppTaxon(**value)
            elif key == temporal_reference_uuid:
                initial[key] = datetime_from_cron(value)
            elif key == geographic_reference_uuid:
                initial[key] = value
            else:
                initial[key] = value

        return initial
示例#4
0
    def serialize_DateTimeJSONField(self, value):

        if value:
            dt = datetime_from_cron(value)
            return dt.isoformat()
        return value
    def get_context(self, name, value, attrs):

        if not value or value == [None, None]:
            value = self.get_default_value()

        elif not isinstance(value, list):
            value = self.decompress(value)

        if (type(value[1]) == str):
            value = [value[0], json.loads(value[1])]

        dt = datetime_from_cron(value[1])

        try:
            year_val, month_val, day_val, hour_val, minute_val = dt.year, dt.month, dt.day, dt.hour, dt.minute
        except AttributeError:
            year_val = month_val = day_val = hour_val = minute_val = None
            if isinstance(value, str):
                if settings.USE_L10N:
                    try:
                        input_format = get_format('DATE_INPUT_FORMATS')[0]
                        v = datetime.datetime.strptime(force_str(value),
                                                       input_format)
                        year_val, month_val, day_val, hour_val, minute_val = v.year, v.month, v.day, v.hour, v.minute
                    except ValueError:
                        pass
                if year_val is None:
                    match = self.date_re.match(value)
                    if match:
                        year_val, month_val, day_val, hour_val, minute_val = [
                            int(val) for val in match.groups()
                        ]

        context = super().get_context(name, value, attrs)

        context['splitwidgets'] = {}

        choices = [(i, i) for i in self.years]
        context['splitwidgets']['year'] = self.create_select(
            'year', name, self.year_field, year_val, choices)

        choices = [(i, i) for i in self.months]
        context['splitwidgets']['month'] = self.create_select(
            'month', name, self.month_field, month_val, choices)

        choices = [(i, i) for i in range(1, 32)]
        context['splitwidgets']['day'] = self.create_select(
            'day', name, self.day_field, day_val, choices)

        choices = [(i, i) for i in self.hours]
        context['splitwidgets']['hour'] = self.create_select(
            'hours', name, self.hour_field, hour_val, choices)

        choices = [(i, i) for i in self.minutes]
        context['splitwidgets']['minute'] = self.create_select(
            'minutes', name, self.minute_field, minute_val, choices)

        context['unixtime'] = int(time.mktime(dt.timetuple()) * 1000)
        context['mode'] = self.attrs.get('datetime_mode', 'datetime')

        #context['value'] = value

        return context
    def update_redundant_columns(self):

        reported_values = self.data['dataset']['reported_values']

        # never alter the user that is assigned
        # in rare cases the following can happen:
        # - loggedin user creates sighting from device.platform=browser
        # - fetching the browser device uid failed
        # -> an unassigned device_uuid is used, the logged in user is linked to the sighting
        # fix this problem and alter self.data['client_id'] to match the users browser client
        if not self.pk:

            # fill self.client_id
            client_id = reported_values['client_id']
            self.client_id = client_id

        # assign a user to the observation - even if it the dataset is updated
        if not self.user and self.client_id:
            # try find a user in usermobiles
            client_id = reported_values['client_id']
            self.client_id = client_id
            client = UserClients.objects.filter(client_id=client_id).first()
            if client:
                self.user = client.user

        # AFTER assigning the user, use the browser client_id if platform is browser
        if not self.pk:

            platform = reported_values['client_platform']

            # use browser client_id if browser and self.user
            # this is only possible if the dataset has been transmitted using django_road, which assigned a user
            if platform == 'browser' and self.user:

                client = UserClients.objects.filter(
                    user=self.user, platform='browser').order_by('pk').first()

                if client:

                    user_browser_client_id = client.client_id

                    if user_browser_client_id != reported_values['client_id']:
                        self.data['dataset']['reported_values'][
                            'client_id'] = user_browser_client_id
                        self.client_id = user_browser_client_id

        # update taxon
        # use the provided observation form json

        observation_form = self.data['dataset']['observation_form']

        taxon_field_uuid = observation_form['taxonomic_reference']

        if taxon_field_uuid in reported_values and type(
                reported_values[taxon_field_uuid]) == dict:
            taxon_json = reported_values[taxon_field_uuid]

            lazy_taxon = self.LazyTaxonClass(**taxon_json)
            self.set_taxon(lazy_taxon)

        # update coordinates or geographic_reference
        # {"type": "Feature", "geometry": {"crs": {"type": "name", "properties": {"name": "EPSG:4326"}},
        # "type": "Point", "coordinates": [8.703575134277346, 55.84336786584161]}, "properties": {"accuracy": 1}}
        # if it is a point, use coordinates. Otherwise use geographic_reference
        geographic_reference_field_uuid = self.data['dataset'][
            'observation_form']['geographic_reference']
        if geographic_reference_field_uuid in self.data['dataset'][
                'reported_values']:

            reported_value = self.data['dataset']['reported_values'][
                geographic_reference_field_uuid]
            if reported_value['geometry']['type'] == 'Point':

                longitude = reported_value['geometry']['coordinates'][0]
                latitude = reported_value['geometry']['coordinates'][1]
                coords = GEOSGeometry('POINT({0} {1})'.format(
                    longitude, latitude),
                                      srid=4326)

                self.coordinates = coords
                self.geographic_reference = coords

        # update temporal reference
        temporal_reference_field_uuid = self.data['dataset'][
            'observation_form']['temporal_reference']

        if temporal_reference_field_uuid in self.data['dataset'][
                'reported_values']:

            reported_value = self.data['dataset']['reported_values'][
                temporal_reference_field_uuid]

            # {"cron": {"type": "timestamp", "format": "unixtime", "timestamp": 1564566855177}, "type": "Temporal"}}
            if reported_value['cron']['type'] == 'timestamp' and reported_value[
                    'cron']['format'] == 'unixtime':
                self.timestamp = datetime_from_cron(reported_value)