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)
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')