def ProcessVisit(user_id, visit_id):
    ''' Accepts a user_id, visit_id, processes all files for that visit + user '''

    PrintTitle('EchoAnalyzer.tasks.ProcessVisit')

    # initialize variables:
    multiprocess_input = []
    result_json_list = []

    # get visit by id, start timer:
    visit = Visit.objects.get(pk=visit_id)
    visit.started_processing_at = datetime.now(timezone.utc)
    visit.save()

    # get list of files associated to visit:
    file_list = list(visit.file_set.all().values_list('id', flat=True))

    # set up multiprocessing pool:
    number_of_threads = len(file_list)
    pool = Pool(number_of_threads)

    # iterate over each file:
    for file_id in file_list:

        # build multiprocess input:
        input_point = {
            'user_id': user_id,
            'visit_id': visit_id,
            'file_id': file_id
        }
        multiprocess_input.append(input_point)

    # multiprocess each file:
    result_json_list = pool.map(MultiProcessFileList, multiprocess_input)

    # delete existing temp data off of server:
    shutil.rmtree(result_json_list[0]['VISIT_DIR'])

    # pack result list as json:
    results = {'results': result_json_list}

    # convert results to json object: (handles json strings where there are NaNs)
    results = json.loads(json.dumps(results).replace('NaN', 'null'))

    # reset database connection for multiprocessing:
    ResetDatabaseConnection()

    # set completed processing time and save results:
    visit = Visit.objects.get(pk=visit_id)
    visit.finished_processing_at = datetime.now(timezone.utc)
    visit.processing_time = datetime.now(
        timezone.utc) - visit.started_processing_at
    visit.results = results
    visit.save()
def HandleUpload(request, visit_id):
    ''' Accepts request, visit_id, downloads files and saves them to visit object '''

    PrintTitle('EchoAnalyzer.views.HandleUpload')

    try:

        # debug:
        print(
            '[EchoAnalyzer.views.HandleUpload]: Got request.FILES.get("filePond") [%s]'
            % request.FILES.get('filePond'))

        # unpack request:
        file_kwargs = {
            'file': request.FILES.get('filePond'),
            'file_name': request.FILES.get('filePond'),
            'dicom_id': None,  # update this field later
            'user': request.user,
            'user_email': request.user.email,
            'visit': Visit.objects.get(pk=visit_id, user=request.user),
        }

        # create file objects and associate to visit:
        file = File.objects.create(**file_kwargs)

        # update dicom_id field:
        file.dicom_id = str(file.file).replace("/staging/", "")
        file.save()

        success = True
        status = 0
        internal_message = 'successfully uploaded file [%s]' % file_kwargs[
            'file_name']
        message = 'Uploaded file successfully.'

    except Exception as error:

        success = False
        status = 1
        internal_message = traceback.format_exc()
        message = 'Error when uploading file.'

    result = {
        'success': success,
        'status': status,
        'message': message,
    }

    print(
        '[EchoAnalyzer.views.HandleUpload]: Status [%d], Internal Message [%s], Message [%s]'
        % (status, internal_message, message))

    return HttpResponse(json.dumps(result))
def LoadResultsPage(request, visit_id):
    ''' Accepts request to results/, checks if pipeline completed '''

    PrintTitle('EchoAnalyzer.views.LoadResultsPage')

    try:

        # debug:
        print(
            '[EchoAnalyzer.views.LoadResultsPage]: Got post request with [%s]'
            % request.POST)

        # unpack post request:
        user = request.user

        # get visit object by id:
        visit = Visit.objects.get(pk=visit_id, user_id=request.user)
        results = visit.results

        # add media links to results object: (must be done on load results page)
        results = AddMediaLinks(results)

        success = True
        status = 0
        internal_message = 'sent results for visit with id [%s]' % visit_id
        message = 'Results sent.'

    except Exception as error:

        results = -1

        success = False
        status = 1
        internal_message = traceback.format_exc()
        message = 'Error, could not find your results.'

    result = {
        'success': success,
        'status': status,
        'message': message,
        'visit_id': visit_id,
        'results': results,
    }

    print(
        '[EchoAnalyzer.views.LoadResultsPage]: Status [%d], Internal Message [%s], Message [%s]'
        % (status, internal_message, message))

    return render(request, 'temp_results.html', context=result)
def CreateDemo(request, visit_id):
    ''' Accepts request to demo/, global variable visit id, loads demo page '''

    PrintTitle('Demo.views.Demo')

    try:

        # debug:
        print('[Demo.views.Demo]: Got post request with [%s]' % request.POST)

        # set demo visit id:
        demo_visit_id = visit_id

        # get visit object by id:
        visit = Visit.objects.get(pk=demo_visit_id)
        results = visit.results

        # add s3 links to media files:
        results = AddMediaLinks(results)

        success = True
        status = 0
        internal_message = 'sent results for visit with id [%s]' % demo_visit_id
        message = 'Results sent.'

    except Exception as error:

        results = -1

        success = False
        status = 1
        internal_message = traceback.format_exc()
        message = 'Error, could not find your results.'

    result = {
        'success': success,
        'status': status,
        'message': message,
        'visit_id': demo_visit_id,
        'results': results,
    }

    print(
        '[EchoAnalyzer.views.LoadResultsPage]: Status [%d], Internal Message [%s], Message [%s]'
        % (status, internal_message, message))

    return render(request, 'temp_results.html', context=result)
def ExecutePipeline(request):
    ''' Accepts request tp /execute_pipeline, executes production pipeline '''

    PrintTitle('EchoAnalyzer.views.ExecutePipeline')

    try:

        # unpack post request:
        user_id = request.user.email
        visit_id = request.POST['visit_id']

        # get visit object by id:
        visit = Visit.objects.get(pk=visit_id, user_id=request.user)

        # debug:
        print(
            '[EchoAnalyzer.views.ExecutePipeline]: Got post request with [%s]'
            % request.POST)

        # execute pipeline if not already started:
        if not visit.started_processing_at:
            ProcessVisit(user_id, visit_id)

        success = True
        status = 0
        internal_message = 'pipeline success for visit with id [%s]' % visit_id
        message = 'Data processed!'

    except Exception as error:

        success = False
        status = 1
        internal_message = traceback.format_exc()
        message = 'Error, could not process your data.'

    result = {
        'success': success,
        'status': status,
        'message': message,
        'visit_id': visit_id,
    }

    print(
        '[EchoAnalyzer.views.ExecutePipeline]: Status [%d], Internal Message [%s], Message [%s]'
        % (status, internal_message, message))

    return HttpResponse(json.dumps(result), content_type='application/json')
def LoadUploadPage(request):
    ''' Accepts request from /upload, creates visit object, renders upload page '''

    PrintTitle('EchoAnalyzer.views.LoadUploadPage')

    # create visit object:
    visit = Visit.objects.create(user=request.user,
                                 user_email=request.user.email)

    # debug:
    print(
        '[EchoAnalyzer.views.Upload] Got request from user with user id [%s]' %
        request.user)
    print(
        '[EchoAnalyzer.views.Upload] Got request from user with visit id [%s]'
        % visit.pk)

    return render(request, 'upload.html', {'visit_id': visit.pk})
def LoadLoaderPage(request, visit_id):
    ''' Accepts request to /loader, renders loader page '''

    PrintTitle('EchoAnalyzer.views.LoadLoaderPage')

    try:

        # debug:
        print(
            '[EchoAnalyzer.views.LoadLoaderPage]: Got post request with [%s]' %
            request.POST)

        # unpack post request:
        user_id = request.user
        #visit_id = request.POST['visit_id']

        success = True
        status = 0
        internal_message = 'routed to loader with user id [%s] and visit id [%s]' % (
            user_id, visit_id)
        message = 'We are processing your data.'

    except Exception as error:

        visit_id = -1

        success = False
        status = 1
        internal_message = error
        message = 'Error when rendering loader page.'

    result = {
        'success': success,
        'status': status,
        'message': message,
        'visit_id': visit_id,
    }

    print(
        '[EchoAnalyzer.views.LoadLoaderPage]: Status [%d], Internal Message [%s], Message [%s]'
        % (status, internal_message, message))

    return render(request, 'loader.html', context=result)