def register():
    if request.method == 'GET':
        return(render_template('RegisterBioreactor.html'));
    elif request.method == 'POST':
        db = client[DB_NAME]
        reactors = db[BIOREACTOR_COLLECTION]

        global_var_collection = db[GLOBAL_VARIABLE_COLLECTION]

        user_data = request.get_json()
        upload_code = bigalgae.generate_digit_code(4)
        experiment_validation_code = bigalgae.generate_digit_code(6)
        validation_key = bigalgae.generate_validation_key(32)
        utc = datetime.datetime.utcnow().isoformat()
        success = False

        while not success:
            try:
                id_str = returnNewID(global_var_collection)

                reactors.insert({'_id': id_str, \
                                'name': user_data['name'], \
                                'location': user_data['location'], \
                                'email': user_data['email'], \
                                'latitude': user_data['latitude'], \
                                'longitude': user_data['longitude'], \
                                'upload_code': upload_code, \
                                'experiment_validation_code': experiment_validation_code, \
                                'validation_key': validation_key, \
                                'validated': False, \
                                'experiments': [], \
                                'created_datetime': utc})
                success = True
            except errors.DuplicateKeyError:
                success = False

        validation_link = url_for('validate', reactor_id=id_str, _external=True) + '?key=' + validation_key
        confirmation_email = MIMEText(render_template('ConfirmationEmail', \
                                                        validation_link = validation_link, \
                                                        reactor_id = id_str))
        confirmation_email['Subject'] = 'Big Algae Open Experiment Validation'

        recipient = user_data['email']

        try:
            bigalgae.send_email(confirmation_email, recipient)
            error_with_email = False
        except smtplib.SMTPAuthenticationError:
            error_with_email = True

        return(url_for('thanks'))
def experiment(reactor_id, experiment_id):
    db = client[DB_NAME]
    reactors = db[BIOREACTOR_COLLECTION]
    exp_search = [res for res in reactors.find({'_id': reactor_id, 'experiments': {'$elemMatch': {'id': experiment_id}}})]
    if len(exp_search) == 0:
        return(render_template('SorryExperiment.html', \
                            reactor_id=reactor_id,  \
                            experiment_id=experiment_id))
    else:
        experiment_dict = exp_search[0]['experiments'][int(experiment_id)-1]
        if request.method == 'GET':
            return(render_template('ExperimentPage.html', \
                                reactor_id=reactor_id, \
                                experiment_dict=experiment_dict,
                                incorrect_upload_code=False,
                                twitter_thanks=False,
                                incorrect_password_dry_mass=False,
                                analyse_image_output=[0]))
        if request.method == 'POST':
            if request.form['submit_button'] == 'SUBMIT DRY MASS':
                file_name_to_update = request.form['file_name_input']
                dry_mass_list = bigalgae.process_advanced_measurements_string(request.form['dry_mass'])
                upload_code_provided = request.form['upload_validation_dry_mass']
                print(dry_mass_list)
                if exp_search[0]['upload_code'] == upload_code_provided:
                    reactor = reactors.find_and_modify({'_id': reactor_id, \
                                            'experiments': {'$elemMatch': {'id': experiment_id}}}, \
                                            {'$pull': {'experiments.$.measurements': \
                                                {'file_name': file_name_to_update}
                                            }})

                    for experiment in reactor['experiments']:
                        if experiment['id'] == experiment_id:
                            for measurement in experiment['measurements']:
                                if measurement['file_name'] == file_name_to_update:
                                    measurement_to_update = measurement

                    measurement_to_update['dry_mass'] += dry_mass_list

                    reactor = reactors.find_and_modify({'_id': reactor_id, \
                                            'experiments': {'$elemMatch': {'id': experiment_id}}}, \
                                            {'$push': {'experiments.$.measurements': \
                                                measurement_to_update
                                            }}, new=True)

                    experiment_dict = reactor['experiments'][int(experiment_id)-1]

                    return(render_template('ExperimentPage.html', \
                                        reactor_id=reactor_id, \
                                        experiment_dict=experiment_dict,
                                        incorrect_upload_code=False,
                                        twitter_thanks=False,
                                        incorrect_password_dry_mass=False,
                                        dry_mass_thanks=True,
                                        analyse_image_output=[0]))
                else:
                    return(render_template('ExperimentPage.html', \
                                        reactor_id=reactor_id, \
                                        experiment_dict=experiment_dict,
                                        incorrect_upload_code=False,
                                        twitter_thanks=False,
                                        incorrect_password_dry_mass=True,
                                        dry_mass_thanks=False,
                                        analyse_image_output=[0]))

            elif request.form['submit_button'] == 'SUBMIT IMAGE':
                upload_code_provided = request.form['upload_validation_upload']
                if exp_search[0]['upload_code'] == upload_code_provided:
                    file_upload = request.files['upload_picture']
                    cell_count_list = bigalgae.process_advanced_measurements_string(request.form['cell_count'])
                    od680_list = bigalgae.process_advanced_measurements_string(request.form['od680'])
                    od750_list = bigalgae.process_advanced_measurements_string(request.form['od750'])
                    if file_upload and allowed_file(file_upload.filename):
                        original_filename = secure_filename(file_upload.filename)
                        utc = datetime.datetime.utcnow().isoformat()
                        present = True
                        while present:
                            try:
                                saved_filename = bigalgae.generate_validation_key(32) + '.' + original_filename.rsplit('.', 1)[1]
                                fd = os.open(os.path.join(app.config['UPLOAD_FOLDER'], saved_filename), os.O_WRONLY | os.O_CREAT | os.O_EXCL)
                                present = False
                            except OSError, e:
                                if e.errno == errno.EEXIST:
                                    present = True
                                else:
                                    raise
                        f = os.fdopen(fd, 'w')
                        file_upload.save(f)
                        f.close()

                        image_filepath = os.path.join(app.config['UPLOAD_FOLDER'], saved_filename)

                        exif_data = bigalgae.extract_exif_data(image_filepath)
                        for problem_key in ['MakerNote', 'UserComment']:
                            if problem_key in exif_data.keys():
                                try:
                                    unicode(exif_data[problem_key], 'utf-8')
                                except UnicodeDecodeError:
                                    del(exif_data[problem_key])
                        image_information = bigalgae.analyse_image(image_filepath)

                        if image_information[0] == 0:
                            image_binary_info = image_information[1]
                        elif image_information[0] == 2:
                            image_binary_info = {}
                        elif image_information[0] == 1:

                            global_var_collection = db[GLOBAL_VARIABLE_COLLECTION]

                            global_var_collection.find_and_modify({'_id': 'failed_image_analysis'},
                                                                  {'$push': {'list':
                                                                        {'file_name': saved_filename , \
                                                                        'cell_count': cell_count_list, \
                                                                        'od680': od680_list, \
                                                                        'od750': od750_list, \
                                                                        'upload_datetime': utc, \
                                                                        'original_filename': original_filename, \
                                                                        'exif': exif_data}}})

                            return(render_template('ExperimentPage.html', \
                                                reactor_id=reactor_id, \
                                                experiment_dict=experiment_dict,
                                                incorrect_upload_code=False,
                                                twitter_thanks=False,
                                                incorrect_password_dry_mass=False,
                                                analyse_image_output=image_information))

                        reactor = reactors.find_and_modify({'_id': reactor_id, \
                                                'experiments': {'$elemMatch': {'id': experiment_id}}}, \
                                                {'$push': {'experiments.$.measurements': \
                                                    {'file_name': saved_filename , \
                                                    'cell_count': cell_count_list, \
                                                    'od680': od680_list, \
                                                    'od750': od750_list, \
                                                    'dry_mass': [], \
                                                    'cell_count_prediction_mean': None, \
                                                    'cell_count_prediction_sd': None, \
                                                    'od680_prediction_mean': None, \
                                                    'od680_prediction_sd': None, \
                                                    'od750_prediction_mean': None, \
                                                    'od750_prediction_sd': None, \
                                                    'dry_mass_prediction_mean': None, \
                                                    'dry_mass_prediction_sd': None, \
                                                    'upload_datetime': utc, \
                                                    'image_binary_info': image_binary_info, \
                                                    'original_filename': original_filename, \
                                                    'exif': exif_data}
                                                }}, new=True)
                        experiment_dict = reactor['experiments'][int(experiment_id)-1]
                        return(render_template('ExperimentPage.html', \
                                            reactor_id=reactor_id, \
                                            experiment_dict=experiment_dict,
                                            incorrect_upload_code=False,
                                            twitter_thanks=True,
                                            incorrect_password_dry_mass=False,
                                            analyse_image_output=image_information))
                else:
                        return(render_template('ExperimentPage.html', \
                                            reactor_id=reactor_id, \
                                            experiment_dict=experiment_dict,
                                            incorrect_upload_code=True,
                                            twitter_thanks=False,
                                            incorrect_password_dry_mass=False,
                                            analyse_image_output=[0]))