コード例 #1
0
def create_observation_image_in_db(api_data, user, conf=None):
    if IMAGE_FPATH in api_data and IMAGE not in api_data:
        api_data[IMAGE] = File(open(api_data.pop(IMAGE_FPATH), mode='rb'))

    if conf is None:
        conf = {}
    create_observation_unit = conf.get(CREATE_OBSERVATION_UNITS, None)
    try:
        struct = ObservationImageStruct(api_data)
    except ObservationImageValidationError as error:
        print('a', error)
        raise

    uid = hashlib.sha256(struct.image.read()).hexdigest()
    struct.image.seek(0)

    if struct.creation_time:
        timezone = pytz.timezone(TIME_ZONE)
        creation_time = timezone.localize(
            datetime.strptime(struct.creation_time, DATETIME_FORMAT))
    else:
        creation_time = None

    with transaction.atomic():
        observation_unit = _get_or_create_observation_unit(
            struct, create_observation_unit)
        study_belongs_to_user = bool(
            user.groups.filter(name=observation_unit.study.group.name).count())

        if not study_belongs_to_user and not is_user_admin(user):
            msg = 'Can not add observation unit to a study you dont own: {}'
            msg = msg.format(observation_unit.study.group.name)
            raise ValueError(msg)

        try:
            ObservationImage.objects.get(observation_image_uid=uid)
            msg = 'This image already exists in db: study {}, accession {}, uid, {}'
            msg += msg.format(struct.study, struct.accession, uid)
            raise ValueError(msg)
        except ObservationImage.DoesNotExist:
            pass

        try:
            observation = ObservationImage.objects.create(
                observation_image_uid=uid,
                observation_unit=observation_unit,
                image=api_data['image'],
                observer=struct.observer,
                creation_time=creation_time)
        except IntegrityError as error:
            if 'duplicate key value' in str(error):
                msg = 'This image already exists in db: {}'.format(uid)
                raise ValueError(msg)
            raise ValueError(str(error))
        except PermissionError as error:
            raise ValueError(str(error))
        except Exception as error:
            raise ValueError(str(error))

    return observation
コード例 #2
0
def update_study_in_db(validated_data, instance, user):
    study_struct = StudyStruct(api_data=validated_data)
    if (study_struct.name != instance.name):
        msg = 'Can not change id in an update operation'
        raise ValidationError(format_error_message(msg))

    group_belong_to_user = bool(user.groups.filter(name=study_struct.metadata.group).count())

    if not group_belong_to_user and not is_user_admin(user):
        msg = 'Can not change ownership if group does not belong to you : {}'
        msg = msg.format(study_struct.metadata.group)
        raise ValidationError(format_error_message(msg))

    try:
        group = Group.objects.get(name=study_struct.metadata.group)
    except Group.DoesNotExist:
        msg = 'Provided group does not exist in db: {}'
        msg = msg.format(study_struct.metadata.group)
        raise ValidationError(format_error_message(msg))

    instance.description = study_struct.description
    instance.is_active = study_struct.is_active
    instance.group = group
    instance.is_public = study_struct.metadata.is_public
    instance.data = study_struct.data
    instance.start_date = study_struct.start_date
    instance.end_date = study_struct.end_date
    instance.save()
    return instance
コード例 #3
0
    def filter_by_permission(task_ids, user):

        if isinstance(user, AnonymousUser):
            return []
        elif is_user_admin(user):
            return task_ids
        else:
            queryset = UserTasks.objects.filter(user=user,
                                                task_id__in=task_ids)
            return queryset.values_list('task_id', flat=True)
コード例 #4
0
def update_accessionset_in_db(payload, instance, user):
    struct = AccessionSetStruct(payload)

    allowed_changes = set(['is_public', 'group'])
    changes_in_payload = set()
    if instance.institute.code != struct.institute_code:
        changes_in_payload.add('institute')
    if instance.accessionset_number != struct.accessionset_number:
        changes_in_payload.add('accessionset_number')
    db_accessions = set([(accession.institute.code, accession.germplasm_number)
                         for accession in instance.accessions.all()])
    payload_accessions = set([(accession[INSTITUTE_CODE],
                               accession[GERMPLASM_NUMBER])
                              for accession in struct.accessions])

    are_payload_accessions_diff = bool(
        db_accessions.difference(payload_accessions))
    if are_payload_accessions_diff:
        changes_in_payload.add('accessions')

    if instance.is_public != struct.metadata.is_public:
        changes_in_payload.add('is_public')

    if instance.group != struct.metadata.group:
        changes_in_payload.add('group')

    not_allowed_changes = changes_in_payload.difference(allowed_changes)

    if not_allowed_changes:
        msg = "you are not allowed to change accessionsets's: {}"
        msg = msg.format(','.join(not_allowed_changes))
        raise ValidationError(format_error_message(msg))

    group_belong_to_user = bool(
        user.groups.filter(name=struct.metadata.group).count())

    if not group_belong_to_user and not is_user_admin(user):
        msg = 'Can not change ownership if group does not belong to you : {}'
        msg = msg.format(struct.metadata.group)
        raise ValidationError(format_error_message(msg))

    try:
        group = Group.objects.get(name=struct.metadata.group)
    except Group.DoesNotExist:
        msg = 'Provided group does not exist in db: {}'
        msg = msg.format(struct.metadata.group)
        raise ValidationError(format_error_message(msg))

    instance.is_public = struct.metadata.is_public
    instance.owner = group
    instance.save()

    return instance
コード例 #5
0
def _add_plants_to_observation_unit(plants, user, observation_unit):
    for plant in plants:
        try:
            plant = Plant.objects.get(name=plant)
            plant_belongs_to_user = bool(user.groups.filter(name=plant.group.name).count())
            if not plant_belongs_to_user and not is_user_admin(user):
                msg = 'Can not add plant you dont own to observation unit: {}'
                msg = msg.format(plant.name)
                raise ValueError(msg)
        except Plant.DoesNotExist:
            msg = 'The given plant does not exist in {} : {}'
            raise ValueError(msg.format(observation_unit.name, plant))
        observation_unit.plant_set.add(plant)
コード例 #6
0
def update_accession_in_db(validated_data, instance, user):
    accession_struct = AccessionStruct(api_data=validated_data)
    if (accession_struct.institute_code != instance.institute.code or
            accession_struct.germplasm_number != instance.germplasm_number):
        msg = 'Can not change id in an update operation'
        raise ValidationError(format_error_message(msg))

    group_belong_to_user = bool(user.groups.filter(name=accession_struct.metadata.group).count())

    if not group_belong_to_user and not is_user_admin(user):
        msg = 'Can not change ownership if group does not belong to you : {}'
        msg = msg.format(accession_struct.metadata.group)
        raise ValidationError(format_error_message(msg))
    if not is_user_admin(user) and instance.is_public != accession_struct.metadata.is_public:
        msg = 'User can not make accession public or private'
        raise ValidationError(format_error_message(msg))

    try:
        group = Group.objects.get(name=accession_struct.metadata.group)
    except Group.DoesNotExist:
        msg = 'Provided group does not exist in db: {}'
        msg = msg.format(accession_struct.metadata.group)
        raise ValidationError(format_error_message(msg))
    with transaction.atomic():
        instance.is_available = accession_struct.is_available
        instance.conservation_status = accession_struct.conservation_status
        instance.in_nuclear_collection = accession_struct.in_nuclear_collection
        instance.group = group
        instance.is_public = accession_struct.metadata.is_public

        instance.passports.all().delete()
        for passport_struct in accession_struct.passports:
            _create_passport_in_db(passport_struct, instance)

        instance.save()
        return instance
コード例 #7
0
def create_observation_unit_in_db(api_data, user=None):
    try:
        struct = ObservationUnitStruct(api_data)
    except ObservationUnitValidationError as error:
        print(error)
        raise

    if struct.metadata.group:
        msg = 'can not set group while creating the observation unit'
        raise ValueError(msg)
    try:
        study = Study.objects.get(name=struct.study)
    except Study.DoesNotExist:
        msg = 'The study has not been added yet to the database: ' + struct.study
        raise ValueError(msg)
    institute_code = struct.accession[INSTITUTE_CODE]
    germplasm_number = struct.accession[GERMPLASM_NUMBER]
    try:
        accession = Accession.objects.get(institute__code=institute_code,
                                          germplasm_number=germplasm_number)
    except Accession.DoesNotExist:
        msg = 'The given accessoin is not in db: {} {}'.format(institute_code,
                                                               germplasm_number)
        raise ValueError(msg)
    study_belongs_to_user = bool(user.groups.filter(name=study.group.name).count())

    if not study_belongs_to_user and not is_user_admin(user):
        msg = 'Can not add observation unit to a study you dont own: {}'
        msg = msg.format(study.group.name)
        raise ValueError(msg)

    with transaction.atomic():
        try:
            observation_unit = ObservationUnit.objects.create(
                name=struct.name,
                accession=accession,
                level=struct.level,
                replicate=struct.replicate,
                study=study)
        except IntegrityError:
            msg = 'This observation unit already exists in db: {}'.format(struct.name)
            raise ValueError(msg)
        if struct.plants:
            _add_plants_to_observation_unit(struct.plants, user, observation_unit)

    return observation_unit
コード例 #8
0
 def filter_queryset(self, queryset):
     # It filters by the study permissions. And the observations belong
     # to a observation unit that is in a study
     queryset = super().filter_queryset(queryset)
     user = self.request.user
     if isinstance(user, AnonymousUser):
         return queryset.filter(
             observation_unit__study__is_public=True).distinct()
     elif is_user_admin(user):
         return queryset
     else:
         try:
             user_groups = user.groups.all()
         except (IndexError, AttributeError):
             user_groups = None
         if user_groups:
             return queryset.filter(
                 Q(observation_unit__study__is_public=True)
                 | Q(observation_unit__study__group__in=user_groups))
         else:
             return queryset.filter(study__is_public=True)
コード例 #9
0
def update_observation_unit_in_db(validated_data, instance, user):
    struct = ObservationUnitStruct(api_data=validated_data)
    if struct.name != instance.name:
        msg = 'Can not change id in an update operation'
        raise ValidationError(format_error_message(msg))
    try:
        study = Study.objects.get(name=struct.study)
    except Study.DoesNotExist:
        msg = 'The study has not been added yet to the database: ' + struct.study
        raise ValueError(msg)
    institute_code = struct.accession[INSTITUTE_CODE]
    germplasm_number = struct.accession[GERMPLASM_NUMBER]

    try:
        accession = Accession.objects.get(institute__code=institute_code,
                                          germplasm_number=germplasm_number)
    except Accession.DoesNotExist:
        msg = 'The given accessoin is not in db: {} {}'.format(institute_code,
                                                               germplasm_number)
        raise ValueError(msg)

    study_belongs_to_user = bool(user.groups.filter(name=study.group.name).count())

    if not study_belongs_to_user and not is_user_admin(user):
        msg = 'Can not change ownership if study does not belong to you : {}'
        msg = msg.format(study.group.name)
        raise ValidationError(format_error_message(msg))

    instance.accession = accession
    instance.level = struct.level
    instance.replicate = struct.replicate
    instance.study = study

    instance.save()
    plants = [] if struct.plants is None else struct.plants

    instance.plant_set.clear()
    _add_plants_to_observation_unit(plants, user, instance)

    return instance
コード例 #10
0
 def filter_queryset(self, queryset):
     # filter plants by owner and look if they are plublic looing to
     # the observatins units study tahat they belong to
     queryset = super().filter_queryset(queryset)
     user = self.request.user
     if isinstance(user, AnonymousUser):
         return queryset.filter(
             observation_units__study__is_public=True).distinct()
     elif is_user_admin(user):
         return queryset
     else:
         try:
             user_groups = user.groups.all()
         except (IndexError, AttributeError):
             user_groups = None
         if user_groups:
             return queryset.filter(
                 Q(observation_units__study__is_public=True)
                 | Q(group__in=user_groups)).distinct()
         else:
             return queryset.filter(
                 observation_units__study__is_public=True).distinct()
コード例 #11
0
def update_observation_in_db(validated_data, instance, user):
    struct = ObservationStruct(api_data=validated_data)
    if struct.observation_id != instance.observation_id:
        msg = 'Can not change id in an update operation'
        raise ValidationError(format_error_message(msg))
    try:
        observation_variable = ObservationVariable.objects.get(name=struct.observation_variable)
    except ObservationVariable.DoesNotExist:
        msg = 'Observation variable {} does not exist in db'
        msg = msg.format(struct.observation_variable)
        raise ValueError(msg)
    try:
        observation_unit = ObservationUnit.objects.get(name=struct.observation_unit)
    except ObservationUnit.DoesNotExist:
        msg = 'Observation unit {} does not exist in db'
        msg = msg.format(struct.observation_unit)
        raise ValueError(msg)

    study_belongs_to_user = bool(user.groups.filter(name=observation_unit.study.group.name).count())
    if not study_belongs_to_user and not is_user_admin(user):
        msg = 'Can not change observation unit because this is in a study you dont own: {}'
        msg = msg.format(observation_unit.study.name)
        raise ValueError(msg)

    if struct.creation_time:
        timezone = pytz.timezone(TIME_ZONE)
        creation_time = timezone.localize(datetime.strptime(struct.creation_time,
                                                            DATETIME_FORMAT))
    else:
        creation_time = None

    instance.observation_variable = observation_variable
    instance.observation_unit = observation_unit
    instance.value = struct.value
    instance.observer = struct.observer
    instance.creation_time = creation_time

    instance.save()
    return instance
コード例 #12
0
def update_observation_variable_in_db(validated_data, instance, user):
    struct = ObservationVariableStruct(api_data=validated_data)
    if struct.name != instance.name:
        msg = 'Can not change id in an update operation'
        raise ValidationError(format_error_message(msg))

    group_belong_to_user = bool(user.groups.filter(name=struct.metadata.group).count())

    if not group_belong_to_user and not is_user_admin(user):
        msg = 'Can not change ownership if group does not belong to you : {}'
        msg = msg.format(struct.metadata.group)
        raise ValidationError(format_error_message(msg))

    try:
        group = Group.objects.get(name=struct.metadata.group)
    except Group.DoesNotExist:
        msg = 'Provided group does not exist in db: {}'
        msg = msg.format(struct.metadata.group)
        raise ValidationError(format_error_message(msg))
    try:
        scale = Scale.objects.get(name=struct.scale)
    except Scale.DoesNotExist:
        raise ValidationError('Scale not valid: ' + struct.scale)
    try:
        trait = Trait.objects.get(name=struct.trait)
    except Trait.DoesNotExist:
        raise ValidationError('Trait not valid: ' + struct.scale)

    instance.description = struct.description
    instance.trait = trait
    instance.group = group
    instance.method = struct.method
    instance.scale = scale

    instance.save()
    return instance
コード例 #13
0
def create_observation_in_db(api_data, user, conf=None):
    if conf is None:
        conf = {}
    create_observation_unit = conf.get(CREATE_OBSERVATION_UNITS, None)
    try:
        struct = ObservationStruct(api_data)
    except ObservationValidationError as error:
        print('a', error)
        raise
    try:
        observation_variable = ObservationVariable.objects.get(name=struct.observation_variable)
    except ObservationVariable.DoesNotExist:
        msg = 'Observation variable {} does not exist in db'
        msg = msg.format(struct.observation_variable)
        raise ValueError(msg)

    if struct.creation_time:
        timezone = pytz.timezone(TIME_ZONE)
        creation_time = timezone.localize(datetime.strptime(struct.creation_time,
                                                            DATETIME_FORMAT))
    else:
        creation_time = None
    try:
        values = validate_value(str(struct.value), observation_variable)
    except ValueError as error:
        if struct.observation_unit:
            error_row_id = struct.observation_unit
        elif struct.accession and struct.study:
            error_row_id = '{} - {}'.format(struct.accession[GERMPLASM_NUMBER],
                                            struct.study)
        else:
            error_row_id = 'Unknown'
        msg = '{}: {}'.format(error_row_id, error)
        raise ValueError(msg)

    with transaction.atomic():
        observations = []
        for value in values:
            observation_unit = _get_or_create_observation_unit(struct, create_observation_unit)
            study_belongs_to_user = bool(user.groups.filter(name=observation_unit.study.group.name).count())

            if not study_belongs_to_user and not is_user_admin(user):
                msg = 'Can not add observation unit to a study you dont own: {}'
                msg = msg.format(observation_unit.study.group.name)
                raise ValueError(msg)

            try:
                observation = Observation.objects.create(
                    observation_variable=observation_variable,
                    observation_unit=observation_unit,
                    value=value,
                    observer=struct.observer,
                    creation_time=creation_time)
            except IntegrityError as error:
                if 'duplicate key value' in str(error):
                    msg = 'This observation already exists in db'
                    raise ValueError(msg)
                raise ValueError(str(error))
            observations.append(observation)

    # only when creating by bulk we would have more than one value.
    # In this cases the values are not returned. In most cases we can return
    # just the oly one observation

    if len(observations) == 1:
        return observations[0]

    return observations