示例#1
0
def reports(org_label, project_label, report_label):
    ''' creating reports
    /organizations/aquaya/projects/water-quality/reports
        : viewing a list of this project's reports
    /organizations/aquaya/projects/water-quality/reports?create=true
        : create a new report config, immediately redirect to editing
    /organizations/aquaya/projects/water-quality/reports/submitters
        : view a report
    /organizations/aquaya/projects/water-quality/reports/submitters?edit=true
        : edit a report; accepts GET or POST
    '''
    user = User.objects(email=session['email'])[0]
    
    orgs = Organization.objects(label=org_label)
    if not orgs:
        flash('Organization "%s" not found, sorry!' % org_label, 'warning')
        return redirect(url_for('organizations'))
    org = orgs[0]

    # permission-check
    if org not in user.organizations and not user.admin_rights:
        app.logger.error('%s tried to view a project but was \
            denied for want of admin rights' % session['email'])
        abort(404)
    
    # find the project
    projects = Project.objects(label=project_label, organization=org) 
    if not projects:
        flash('Project "%s" not found, sorry!' % project_label, 'warning')
        return redirect(url_for('organizations', org_label=org.label))
    project = projects[0]

    if request.method == 'POST':
        # we have a report_label
        reports = Report.objects(label=report_label, project=project)
        if not reports:
            abort(404)
        report = reports[0]

        form_type = request.form.get('form_type', '')
        if form_type == 'info':
            if report.name != request.form.get('name', ''):
                name = request.form.get('name', '')
                report.update(set__name = name)

                reports = Report.objects(project=project).only('label')
                labels = [r.label for r in reports]
                report.update(set__label = utilities.generate_label(name
                    , labels))

            report.update(set__description = request.form.get('description'
                , ''))

            report.reload()

            flash('Report details saved successfully.', 'success')
            return redirect(url_for('reports', org_label=org.label
                , project_label=project.label, report_label=report.label
                , edit='true'))
        
        elif form_type == 'components':
            # attach components to report
            # 'items' is of the form graph_id__4abcd00123 or statistic_id..
            # convert these to full objects
            items = request.form.getlist('items')
            components = []
            for item in items:
                prefix, item_id = item.split('__')
                item_type = prefix.split('_')[0]

                if item_type == 'graph':
                    graphs = Graph.objects(id=item_id)
                    if not graphs:
                        abort(404)
                    components.append(graphs[0])
                
                elif item_type == 'statistic':
                    statistics = Statistic.objects(id=item_id)
                    if not statistics:
                        abort(404)
                    components.append(statistics[0])
    
            report.update(set__components=components)

            flash('Report components saved successfully.', 'success')
            
            url = url_for('reports', org_label=org.label
                , project_label=project.label, report_label=report.label
                , edit='true')
            return redirect(url + '#components')
       

        elif form_type == 'admin':
            # delete the report
            name = report.name
            report.delete()
            app.logger.info('%s deleted report "%s"' % \
                (session['email'], name))
            flash('report "%s" was deleted successfully' % name, 'success')
            return redirect(url_for('reports', org_label=org.label
                , project_label=project.label))
        
        else:
            # bad 'form_type'
            abort(404)
       
        
    
    if request.method == 'GET':
        if report_label:
            reports = Report.objects(label=report_label, project=project)
            if not reports:
                app.logger.error('%s tried to access a report that does \
                    not exist' % session['email'])
                flash('Report "%s" not found, sorry!' % report_label
                    , 'warning')
                return redirect(url_for('projects', org_label=org.label
                    , project_label=project.label))
            report = reports[0]

            if request.args.get('edit', '') == 'true':
                # extract the component names for js typeahead
                available_graphs = Graph.objects(project=project)
                available_statistics = Statistic.objects(project=project)

                return render_template('report_edit.html'
                    , report=report
                    , available_graphs = available_graphs
                    , available_statistics = available_statistics)


            elif request.args.get('preview', '') == 'true':
                # create pdf preview of the report
                # calculate all statistics and graph datasets
                items = _generate_report_items(report)
                
                # get the current time
                current_time = datetime.datetime.utcnow()

                return render_template('report_preview.html', report=report
                    , items=items, current_time=current_time)

            
            elif request.args.get('render', '') == 'true':
                ''' create PDF versions of the preview
                also send them to s3
                '''

                # CSRF validation
                token = request.args.get('token', '')
                if not verify_token(token):
                    abort(403)

                utilities.create_rendering(report)
                
                flash('The report is now being rendered, this process may \
                    take a few moments.  Check the table below for \
                    updates', 'info')
                return redirect(url_for('reports', org_label=org.label
                    , project_label=project.label, report_label=report.label))

            else:
                # find all relevant renderings
                renderings = Rendering.objects(report=report).order_by(
                    '-creation_time')

                return render_template('report.html', report=report
                    , renderings=renderings)

        if request.args.get('create', '') == 'true':
            # create a new report

            # CSRF validation
            token = request.args.get('token', '')
            if not verify_token(token):
                abort(403)

            try:
                report_name = 'report-%s' \
                    % utilities.generate_random_string(6)
                new_report= Report(
                    creation_time = datetime.datetime.utcnow()
                    , creator = user
                    , label = report_name.lower()
                    , project = project
                    , name = report_name
                    , public_label = utilities.generate_random_string(24)
                )
                new_report.save() 
                app.logger.info('report created by %s' % session['email'])
                flash('Report created, please change the default values.'
                    , 'success')
            except:
                app.logger.error('report creation failed for %s' % \
                    session['email'])
                flash('There was an error, sorry :/', 'error')
                return redirect(url_for('projects', org_label=org.label
                    , project=project.label))
            
            # redirect to the editing screen
            return redirect(url_for('reports', org_label=org.label
                , project_label=project.label
                , report_label=new_report.label, edit='true'))
        
        # no statistic in particular was specified; show em all
        reports = Report.objects(project=project)

        return render_template('project_reports.html', project=project
            , reports=reports)
示例#2
0
文件: tasks.py 项目: aquaya/pipeline
def send_scheduled_report(schedule_id):
    ''' starts rendering pdfs and prepares to send the message
    '''
    schedules = Schedule.objects(id=schedule_id)
    if not schedules:
        # the schedule was deleted
        return False
    schedule = schedules[0]
    print 'sending scheduled report for organization "%s", project "%s", \
        schedule "%s"' % (schedule.project.organization.name
        , schedule.project.name, schedule.name)
    
    # validate the schedule config for email and sms messages
    if not ready_to_send(schedule):
        print 'bad schedule config for "%s"' % schedule.name
        return False
    
    if schedule.message_type == 'email':
        # start rendering the reports
        new_renderings = []
        for report in schedule.reports:
            # instantiates a new rendering
            # also enqueues pdf-generation
            rendering = utilities.create_rendering(report)
            new_renderings.append(rendering)
    
        # create a new message
        new_message = Message(
            creation_time = datetime.datetime.utcnow()
            , message_type = schedule.message_type
            , recipients = schedule.email_recipients
            , renderings = new_renderings
            , schedule = schedule)
        new_message.save()

        # locally save the project data if we need to attach it
        if schedule.send_project_data:
            absolute_filename = utilities.download_all_entries(schedule.project
                , schedule.data_filters
                , format='xls'
                , apply_any_filters=schedule.apply_any_filters)

            new_message.update(set__project_data_path=absolute_filename)

        # compute the statistics and attach them to the message
        if schedule.statistics:
            text_results = []
            for statistic in schedule.statistics:
                result = utilities.format_statistic_result(statistic)
                text_results.append(result)

            new_message.update(set__statistic_results = text_results)

        # send the message
        # will wait until renderings are finished, if necessary
        redis_config = app.config['REDIS_CONFIG']
        use_connection(Redis(redis_config['host'], redis_config['port']
                , password=redis_config['password']))
        queue = Queue()
        queue.enqueue(send_scheduled_message, new_message.id)


    elif schedule.message_type == 'sms':
        # compute any statistics
        text_results = []
        if schedule.statistics:
            for statistic in schedule.statistics:
                result = utilities.format_statistic_result(statistic)
                text_results.append(result)

        # we create a job for each recipient
        for recipient in schedule.sms_recipients:
            # create a new message
            new_message = Message(
                creation_time = datetime.datetime.utcnow()
                , message_type = schedule.message_type
                , recipients = [recipient]
                , schedule = schedule
                , statistic_results = text_results)
            new_message.save()

            # send each message
            redis_config = app.config['REDIS_CONFIG']
            use_connection(Redis(redis_config['host'], redis_config['port']
                    , password=redis_config['password']))
            queue = Queue()
            queue.enqueue(send_scheduled_message, new_message.id)

    
    # and schedule the next job
    update_scheduled_send(schedule.id)
    app.logger.info('schedule interval updated')