'Update a Project
Update various attributes and configurable settings for the given
project.  Only supplied values are updated.
:pparam string organization_slug: the slug of the organization the
project belongs to.
:pparam string project_slug: the slug of the project to delete.
:param string name: the new name for the project.
:param string slug: the new slug for the project.
:param string platform: the new platform for the project.
:param boolean isBookmarked: in case this API call is invoked with a
user context this allows changing of
the bookmark flag.
:param int digestsMinDelay:
:param int digestsMaxDelay:
:param object options: optional options to override in the
project settings.
:auth: required'

@attach_scenarios([update_project_scenario])
def put(self, request, project):

    has_project_write = ((request.auth and request.auth.has_scope('project:write')) or (request.access and request.access.has_scope('project:write')))
    if has_project_write:
        serializer_cls = ProjectAdminSerializer
    else:
        serializer_cls = ProjectMemberSerializer
    serializer = serializer_cls(data=request.DATA, partial=True)
    if (not serializer.is_valid()):
        return Response(serializer.errors, status=400)
    result = serializer.object
    changed = False
    if result.get('slug'):
        project.slug = result['slug']
        changed = True
    if result.get('name'):
        project.name = result['name']
        changed = True
    if result.get('platform'):
        project.platform = result['platform']
        changed = True
    if changed:
        project.save()
    if result.get('isBookmarked'):
        try:
            with transaction.atomic():
                ProjectBookmark.objects.create(project_id=project.id, user=request.user)
        except IntegrityError:
            pass
    elif (result.get('isBookmarked') is False):
        ProjectBookmark.objects.filter(project_id=project.id, user=request.user).delete()
    if result.get('digestsMinDelay'):
        project.update_option('digests:mail:minimum_delay', result['digestsMinDelay'])
    if result.get('digestsMaxDelay'):
        project.update_option('digests:mail:maximum_delay', result['digestsMaxDelay'])
    if result.get('subjectPrefix'):
        project.update_option('mail:subject_prefix', result['subjectPrefix'])
    if result.get('subjectTemplate'):
        project.update_option('mail:subject_template', result['subjectTemplate'])
    if result.get('isSubscribed'):
        UserOption.objects.set_value(user=request.user, key='mail:alert', value=1, project=project)
    elif (result.get('isSubscribed') is False):
        UserOption.objects.set_value(user=request.user, key='mail:alert', value=0, project=project)
    if has_project_write:
        options = request.DATA.get('options', {})
        if ('sentry:origins' in options):
            project.update_option('sentry:origins', clean_newline_inputs(options['sentry:origins']))
        if ('sentry:resolve_age' in options):
            project.update_option('sentry:resolve_age', int(options['sentry:resolve_age']))
        if ('sentry:scrub_data' in options):
            project.update_option('sentry:scrub_data', bool(options['sentry:scrub_data']))
        if ('sentry:scrub_defaults' in options):
            project.update_option('sentry:scrub_defaults', bool(options['sentry:scrub_defaults']))
        if ('sentry:safe_fields' in options):
            project.update_option('sentry:safe_fields', [s.strip().lower() for s in options['sentry:safe_fields']])
        if ('sentry:sensitive_fields' in options):
            project.update_option('sentry:sensitive_fields', [s.strip().lower() for s in options['sentry:sensitive_fields']])
        if ('sentry:csp_ignored_sources_defaults' in options):
            project.update_option('sentry:csp_ignored_sources_defaults', bool(options['sentry:csp_ignored_sources_defaults']))
        if ('sentry:csp_ignored_sources' in options):
            project.update_option('sentry:csp_ignored_sources', clean_newline_inputs(options['sentry:csp_ignored_sources']))
        if ('feedback:branding' in options):
            project.update_option('feedback:branding', ('1' if options['feedback:branding'] else '0'))
        if ('sentry:reprocessing_active' in options):
            project.update_option('sentry:reprocessing_active', bool(options['sentry:reprocessing_active']))
        if ('filters:blacklisted_ips' in options):
            project.update_option('sentry:blacklisted_ips', clean_newline_inputs(options['filters:blacklisted_ips']))
        if ('filters:{}'.format(FilterTypes.RELEASES) in options):
            if features.has('projects:additional-data-filters', project, actor=request.user):
                project.update_option('sentry:{}'.format(FilterTypes.RELEASES), clean_newline_inputs(options['filters:{}'.format(FilterTypes.RELEASES)]))
            else:
                return Response({'detail': ['You    do    not    have    that    feature    enabled']}, status=400)
        if ('filters:{}'.format(FilterTypes.ERROR_MESSAGES) in options):
            if features.has('projects:additional-data-filters', project, actor=request.user):
                project.update_option('sentry:{}'.format(FilterTypes.ERROR_MESSAGES), clean_newline_inputs(options['filters:{}'.format(FilterTypes.ERROR_MESSAGES)], case_insensitive=False))
            else:
                return Response({'detail': ['You    do    not    have    that    feature    enabled']}, status=400)
        self.create_audit_entry(request=request, organization=project.organization, target_object=project.id, event=AuditLogEntryEvent.PROJECT_EDIT, data=project.get_audit_log_data())
    data = serialize(project, request.user, DetailedProjectSerializer())
    return Response(data)
