def get_in_touch(admin_client, uuid):
    template_context = base_template_context()
    template_context.update({'user': session['oauth_user']})
    return render_template('builder/user_satisfaction/get-in-touch.html',
                           email=app.config['NOTIFICATIONS_EMAIL'],
                           uuid=uuid,
                           **template_context)
def api_get_in_touch(admin_client, uuid):
    template_context = base_template_context()
    template_context.update({'user': session['oauth_user']})
    return render_template('builder/digital_take_up/api-get-in-touch.html',
                           email=app.config['NOTIFICATIONS_EMAIL'],
                           uuid=uuid,
                           **template_context)
def add_user_satisfaction(admin_client, uuid):
    template_context = base_template_context()
    template_context.update({
        'user': session['oauth_user'],
    })
    form = DonePageURLForm()
    if form.validate_on_submit():
        url = form.data['done_page_url']
        match = re.search('/done/([^/?]+)', url)
        if match is None:
            return redirect(url_for('get_in_touch', uuid=uuid))
        data_group = match.group(1)
        data_type = 'user-satisfaction-score'
        data_set = admin_client.get_data_set(data_group, data_type)
        if data_set is None:
            return redirect(url_for('get_in_touch', uuid=uuid))
        module_config = _module_config({
            'data_group': data_group,
            'data_type': data_type,
            'type_id': _get_user_satisfaction_module_type(admin_client)['id']})
        admin_client.add_module_to_dashboard(uuid, module_config)
        return redirect(url_for('dashboard_hub', uuid=uuid))
    if form.errors:
        flash(to_error_list(form.errors), 'danger')
    return render_template(
        'builder/user_satisfaction/add.html',
        uuid=uuid,
        form=form,
        **template_context)
def channel_options(admin_client, uuid):
    template_context = base_template_context()
    template_context.update({
        'user': session['oauth_user'],
    })
    form = ChannelOptionsForm()
    if request.method == 'POST':
        if True in form.data.values():
            session['channel_choices'] = [
                key for key, val in form.data.items() if val
            ]

            dashboard = admin_client.get_dashboard(uuid)
            owning_organisation = (dashboard.get('organisation')
                                   or {}).get("name", 'Unknown')

            module_config = get_module_config_for_digital_takeup(
                owning_organisation)

            create_dataset_and_module('transactions-by-channel', admin_client,
                                      uuid, session['upload_choice'],
                                      'single_timeseries', module_config,
                                      dashboard["slug"], 'digital-takeup')

            return redirect(url_for('upload_digital_take_up', uuid=uuid))
        else:
            error = 'Please select one or more channel options.'
            flash(error, 'danger')
    return render_template('builder/digital_take_up/channel-options.html',
                           uuid=uuid,
                           form=form,
                           **template_context)
def add_user_satisfaction(admin_client, uuid):
    template_context = base_template_context()
    template_context.update({
        'user': session['oauth_user'],
    })
    form = DonePageURLForm()
    if form.validate_on_submit():
        url = form.data['done_page_url']
        match = re.search('/done/([^/?]+)', url)
        if match is None:
            return redirect(url_for('get_in_touch', uuid=uuid))
        data_group = match.group(1)
        data_type = 'user-satisfaction-score'
        data_set = admin_client.get_data_set(data_group, data_type)
        if data_set is None:
            return redirect(url_for('get_in_touch', uuid=uuid))
        module_config = _module_config({
            'data_group':
            data_group,
            'data_type':
            data_type,
            'type_id':
            _get_user_satisfaction_module_type(admin_client)['id']
        })
        admin_client.add_module_to_dashboard(uuid, module_config)
        return redirect(url_for('dashboard_hub', uuid=uuid))
    if form.errors:
        flash(to_error_list(form.errors), 'danger')
    return render_template('builder/user_satisfaction/add.html',
                           uuid=uuid,
                           form=form,
                           **template_context)
def internal_error(err):
    template_context = base_template_context()
    template_context.update({
        'user': session['oauth_user'],
    })
    app.logger.info(traceback.format_exc())
    return render_template('error.html',
                           error="There has been an error",
                           **template_context), 500
def root():
    if signed_in(session):
        return redirect(url_for('upload_list_data_sets'))
    elif signed_in_no_access(session):
        template_context = base_template_context()
        template_context.update({'user': session['oauth_user']})
        return render_template('index.html', **template_context)
    else:
        return redirect(get_authorization_url(session))
def confirmation():
    session.pop('full_name', None)
    session.pop('email_address', None)
    session.pop('organisation_name', None)
    session.pop('service_name', None)
    session.pop('service_url', None)
    session.pop('service_description', None)
    template_context = base_template_context()
    return render_template('registrations/confirmation.html',
                           **template_context)
def get_in_touch(admin_client, uuid):
    template_context = base_template_context()
    template_context.update({
        'user': session['oauth_user']
    })
    return render_template(
        'builder/user_satisfaction/get-in-touch.html',
        email=app.config['NOTIFICATIONS_EMAIL'],
        uuid=uuid,
        **template_context)
def confirmation():
    session.pop('full_name', None)
    session.pop('email_address', None)
    session.pop('organisation_name', None)
    session.pop('service_name', None)
    session.pop('service_url', None)
    session.pop('service_description', None)
    template_context = base_template_context()
    return render_template(
        'registrations/confirmation.html',
        **template_context)
def upload_cost_per_transaction(admin_client, uuid):
    template_context = base_template_context()
    template_context.update({'user': session['oauth_user']})

    if 'upload_data' in session:
        upload_data = session.pop('upload_data')
        template_context['upload_data'] = upload_data

    return render_template('builder/cost_per_transaction/upload.html',
                           uuid=uuid,
                           data_type=DATA_TYPE,
                           **template_context)
def dashboard_delete(admin_client, uuid):
    template_context = base_template_context()
    template_context.update({
        'user': session['oauth_user'],
    })
    dashboard_dict = admin_client.get_dashboard(uuid)
    if dashboard_dict['status'] == 'unpublished':
        admin_client.delete_dashboard(uuid)
        flash(dashboard_dict['title'] + ' deleted', 'info')
        return redirect(url_for('dashboard_list'))
    else:
        flash('Cannot delete published dashboard', 'info')
        return redirect(url_for('dashboard_list'))
def about_your_service():
    form = AboutYourServiceForm()
    template_context = base_template_context()
    if form.validate_on_submit():
        session['service_name'] = form.data['service_name']
        session['service_url'] = form.data['service_url']
        session['service_description'] = form.data['service_description']
        send_application_email()
        return redirect(url_for('confirmation'))
    if form.errors:
        flash(to_error_list(form.errors), 'danger')
    return render_template('registrations/about-your-service.html',
                           form=form,
                           **template_context)
def upload_digital_take_up(admin_client, uuid):
    template_context = base_template_context()
    template_context.update({
        'user': session['oauth_user'],
    })

    if 'upload_data' in session:
        upload_data = session.pop('upload_data')
        template_context['upload_data'] = upload_data

    return render_template('builder/digital_take_up/upload.html',
                           uuid=uuid,
                           data_type=DATA_TYPE,
                           **template_context)
def clone_module(admin_client, target_dashboard_uuid=None):
    modules = None
    dashboards = None
    target_dashboard_url = None
    source_dashboard_uuid = None
    selected_dashboard = None

    dashboards_url = '{0}/dashboards'.format(
        app.config['STAGECRAFT_HOST'])
    access_token = session['oauth_token']['access_token']
    headers = {
        'Authorization': 'Bearer {0}'.format(access_token),
    }
    dashboard_response = requests.get(dashboards_url, headers=headers)
    if dashboard_response.status_code == 200:
        dashboards = dashboard_response.json()
        if request.form and 'dashboard_uuid' in request.form:
            source_dashboard_uuid = request.form['dashboard_uuid']
            modules = admin_client.list_modules_on_dashboard(
                source_dashboard_uuid)
            selected_dashboard = next(
                dashboard for dashboard in dashboards
                if dashboard['id'] == source_dashboard_uuid)

    if target_dashboard_uuid:
        target_dashboard_url = '/admin/dashboards/{}'.format(
            target_dashboard_uuid)
        if 'pending_dashboard' not in session:
            # Flash something here? This has happened
            # because the user has got to the clone dashboard page
            # via the url, not via the clone dashboard button.
            # As a result there is no pending dashboard data.
            return redirect(target_dashboard_url)
        target_dashboard_name = session['pending_dashboard']['title']
    else:
        target_dashboard_url = '/admin/dashboards/new'
        target_dashboard_name = 'new dashboard'

    template_context = base_template_context()
    template_context['user'] = session['oauth_user']

    return render_template('dashboards/clone_module.html',
                           modules=modules,
                           dashboards=dashboards,
                           target_dashboard_url=target_dashboard_url,
                           source_dashboard_uuid=source_dashboard_uuid,
                           selected_dashboard=selected_dashboard,
                           target_dashboard_uuid=target_dashboard_uuid,
                           target_dashboard_name=target_dashboard_name,
                           **template_context)
def upload_cost_per_transaction(admin_client, uuid):
    template_context = base_template_context()
    template_context.update({
        'user': session['oauth_user']
    })

    if 'upload_data' in session:
        upload_data = session.pop('upload_data')
        template_context['upload_data'] = upload_data

    return render_template('builder/cost_per_transaction/upload.html',
                           uuid=uuid,
                           data_type=DATA_TYPE,
                           **template_context)
def about_you():
    admin_client = AdminAPI(app.config['STAGECRAFT_HOST'], None)
    form = AboutYouForm(admin_client)
    template_context = base_template_context()
    if form.validate_on_submit():
        session['full_name'] = form.data['full_name']
        session['email_address'] = form.data['email_address']
        session['organisation_name'] = get_organisation_name(
            form.data['organisation'], form.organisation.choices)
        return redirect(url_for('about_your_service'))
    if form.errors:
        flash(to_error_list(form.errors), 'danger')
    return render_template('registrations/about-you.html',
                           form=form,
                           **template_context)
def about_your_service():
    form = AboutYourServiceForm()
    template_context = base_template_context()
    if form.validate_on_submit():
        session['service_name'] = form.data['service_name']
        session['service_url'] = form.data['service_url']
        session['service_description'] = form.data['service_description']
        send_application_email()
        return redirect(url_for('confirmation'))
    if form.errors:
        flash(to_error_list(form.errors), 'danger')
    return render_template(
        'registrations/about-your-service.html',
        form=form,
        **template_context)
def about_you():
    admin_client = AdminAPI(app.config['STAGECRAFT_HOST'], None)
    form = AboutYouForm(admin_client)
    template_context = base_template_context()
    if form.validate_on_submit():
        session['full_name'] = form.data['full_name']
        session['email_address'] = form.data['email_address']
        session['organisation_name'] = get_organisation_name(
            form.data['organisation'], form.organisation.choices)
        return redirect(url_for('about_your_service'))
    if form.errors:
        flash(to_error_list(form.errors), 'danger')
    return render_template(
        'registrations/about-you.html',
        form=form,
        **template_context)
def dashboard_clone(admin_client):
    template_context = base_template_context()
    template_context['user'] = session['oauth_user']
    dashboard_dict = admin_client.get_dashboard(request.args.get('uuid'))
    form = convert_to_dashboard_form(
        dashboard_dict,
        admin_client,
        ModuleTypes(admin_client),
        DataSources(admin_client, session['oauth_token']['access_token']))
    form['title'].data = ''
    form['slug'].data = ''
    form['published'].data = False
    for m in form.modules:
        m['id'].data = ''
    return render_template('admin/dashboards/create.html',
                           form=form,
                           **template_context)
def dashboard_list(admin_client):
    template_context = base_template_context()
    template_context.update({
        'user': session['oauth_user'],
    })

    dashboard_response = admin_client.get_dashboards()

    if dashboard_response:
        if len(dashboard_response) == 0:
            flash('No dashboards stored', 'info')
    else:
        flash('Could not retrieve the list of dashboards', 'danger')

    return render_template('dashboards/index.html',
                           dashboards=dashboard_response,
                           **template_context)
def upload_list_data_sets(admin_client):
    template_context = base_template_context()
    try:
        data_sets = group_by_group(admin_client.list_data_sets())
    except HTTPError as err:
        if err.response.status_code == 401:
            return redirect(url_for('oauth_sign_out'))
        else:
            raise

    template_context.update({
        'user': session['oauth_user'],
        'data_sets': data_sets
    })
    if 'upload_data' in session:
        upload_data = session.pop('upload_data')
        template_context['upload_data'] = upload_data
    return render_template('data_sets.html', **template_context)
def upload_cost_per_transaction_success(admin_client, uuid):
    template_context = base_template_context()
    template_context.update({'user': session['oauth_user']})
    dashboard = admin_client.get_dashboard(uuid)

    template_context.update(({
        'dashboard': {
            'title': dashboard["title"],
            'module': {
                'title': session['module']
            }
        },
        'admin_host': app.config['ADMIN_HOST'],
        'upload_period': 'quarterly'
    }))

    return render_template('builder/cost_per_transaction/upload-success.html',
                           uuid=uuid, **template_context)
def upload_cost_per_transaction_success(admin_client, uuid):
    template_context = base_template_context()
    template_context.update({'user': session['oauth_user']})
    dashboard = admin_client.get_dashboard(uuid)

    template_context.update(({
        'dashboard': {
            'title': dashboard["title"],
            'module': {
                'title': session['module']
            }
        },
        'admin_host': app.config['ADMIN_HOST'],
        'upload_period': 'quarterly'
    }))

    return render_template('builder/cost_per_transaction/upload-success.html',
                           uuid=uuid,
                           **template_context)
def upload_options(admin_client, uuid):
    template_context = base_template_context()
    template_context.update({
        'user': session['oauth_user'],
    })

    form = UploadOptionsForm()
    if form.validate_on_submit():
        session['upload_choice'] = form.data['upload_option']
        if session['upload_choice'] != 'api':
            return redirect(url_for('channel_options', uuid=uuid))
        else:
            return redirect(url_for('api_get_in_touch', uuid=uuid))
    if form.errors:
        flash(to_error_list(form.errors), 'danger')
    return render_template(
        'builder/digital_take_up/upload-options.html',
        uuid=uuid,
        upload_options=[option for option in form.upload_option],
        form=form,
        **template_context)
def upload_digital_take_up_success(admin_client, uuid):
    template_context = base_template_context()
    template_context.update({
        'user': session['oauth_user'],
    })

    dashboard = admin_client.get_dashboard(uuid)

    template_context.update(({
        'dashboard': {
            'title': dashboard["title"],
            'module': {
                'title': session['module']
            }
        },
        'admin_host': app.config['ADMIN_HOST'],
        'upload_period': session['upload_choice']
    }))

    return render_template('builder/digital_take_up/upload_success.html',
                           uuid=uuid,
                           **template_context)
def dashboard_hub(admin_client, uuid):
    template_context = base_template_context()
    template_context.update({
        'user': session['oauth_user'],
    })
    dashboard_dict = admin_client.get_dashboard(uuid)

    if dashboard_dict['status'] != 'unpublished':
        flash('In review or published dashboards cannot be edited', 'info')
        return redirect(url_for('dashboard_list'))

    Dashboard = namedtuple('Dashboard', dashboard_dict.keys())
    dashboard = Dashboard(**dashboard_dict)
    modules = []
    if "modules" in dashboard_dict.keys():
        modules = [module["data_type"] for module in dashboard_dict["modules"]
                   if 'data_type' in module]
    form = DashboardHubForm(obj=dashboard)
    if form.validate_on_submit():
        data = form.data
        data["slug"] = dashboard_dict["slug"]
        admin_client.update_dashboard(uuid, data)
        flash('Your dashboard has been updated', 'success')
        return redirect(url_for('dashboard_hub', uuid=uuid))
    if form.errors:
        flash(to_error_list(form.errors), 'danger')

    preview_url = "{0}/performance/{1}".format(
        app.config['GOVUK_SITE_URL'], dashboard_dict['slug'])
    return render_template(
        'builder/dashboard-hub.html',
        uuid=uuid,
        dashboard_title=dashboard.title,
        preview_url=preview_url,
        form=form,
        modules=modules,
        **template_context)
def start():
    template_context = base_template_context()
    return render_template('registrations/start.html', **template_context)
def start():
    template_context = base_template_context()
    return render_template('registrations/start.html', **template_context)
def dashboard_form(admin_client, uuid=None):
    def should_use_session(session, uuid):
        if 'pending_dashboard' not in session:
            return False
        if uuid is None:
            return True
        if session['pending_dashboard'].get('uuid') == uuid:
            return True
        return False

    def append_cloned_module():
        if request.args.get('clone_module'):
            module = admin_client.get_module(
                request.args.get('clone_module'))
            module_form = convert_to_module_for_form(
                module, module_types, cloned=True)
            form.modules.append_entry(module_form)
            add_select_options_to_module()

    def append_new_module_forms():
        total_modules = int(request.args.get('modules'))
        modules_required = total_modules - len(form.modules)
        for i in range(modules_required):
            form.modules.append_entry()
            add_select_options_to_module()

    def add_select_options_to_module():
        choices = module_types.get_visualisation_choices()
        form.modules[-1].module_type.choices = choices
        choices = data_sources.group_choices()
        form.modules[-1].data_group.choices = choices
        choices = data_sources.type_choices()
        form.modules[-1].data_type.choices = choices

    template_context = base_template_context()
    template_context['user'] = session['oauth_user']
    if uuid is not None:
        template_context['uuid'] = uuid

    module_types = ModuleTypes(admin_client)
    data_sources = DataSources(
        admin_client, session['oauth_token']['access_token'])
    if should_use_session(session, uuid):
        form = DashboardCreationForm(admin_client,
                                     module_types,
                                     data_sources,
                                     data=session['pending_dashboard'])
    elif uuid is None:
        form = DashboardCreationForm(admin_client,
                                     module_types,
                                     data_sources,
                                     request.form)
    else:
        dashboard_dict = admin_client.get_dashboard(uuid)
        form = convert_to_dashboard_form(
            dashboard_dict, admin_client, module_types, data_sources)

    if 'pending_dashboard' in session:
        del session['pending_dashboard']

    if request.args.get('modules'):
        append_new_module_forms()
        if request.args.get('section'):
            form.modules[-1].category.data = 'container'
    if request.args.get('clone_module'):
        append_cloned_module()

    return render_template('admin/dashboards/create.html',
                           form=form,
                           **template_context)