def profile_dashboard(dashboard_id_str=None, dashboard_name=None): if not auth.access_profile(): return redirect(url_for('bp_mqe.login', next='dashboard')) g.profile_page = 'dashboard' dbs = dashboards.OwnerDashboards(auth.logged_owner_id()) if dashboard_id_str is None: active_db_id = dbs.dashboards[0].dashboard_id else: try: active_db_id = uuid.UUID(dashboard_id_str) except ValueError: abort(404) if active_db_id not in dbs.dashboard_by_id: abort(404) layout = Layout.select(auth.logged_owner_id(), active_db_id) if not reports.owner_has_reports(auth.logged_owner_id()): onboarding = True else: onboarding = False return render_template('profile_dashboard.html', onboarding=onboarding, dashboards=dbs, active_db_id=active_db_id, active_db_layout_id=layout.layout_id, active_db_layout_dict=layout.layout_dict)
def render_dashboard(): dashboard_id = request.get_json()['dashboard_id'] check_access(lambda: auth.access_dashboard(dashboard_id)) db = dashboards.Dashboard.select(auth.logged_owner_id(), dashboard_id) if not db: return error('Invalid dashboard') layout = Layout.select(auth.logged_owner_id(), dashboard_id) html = get_template_attribute('m.html', 'dashboard')(db, layout.layout_id if layout else None, layout.layout_dict if layout else None) return success(result=dict(html=html))
def create_tile(): dashboard_id = request.get_json()['dashboard_id'] report_id = request.get_json().get('report_id') report_instance_id = request.get_json().get('report_instance_id') tile_config = request.get_json()['tile_config'] moveresize = request.get_json()['moveresize'] for_layout_id = request.get_json()['for_layout_id'] check_access(lambda: auth.access_dashboard(dashboard_id)) check_access(lambda: auth.access_report_instances(report_id)) if tile_config['tags']: tile_config['tile_options']['tpcreator_uispec'] = tpcreator.suggested_tpcreator_uispec( tile_config['tags']) tile = tiles.Tile.insert(auth.logged_owner_id(), report_id, dashboard_id, tile_config) mres = layouts.place_tile(tile, for_layout_id=for_layout_id) if not mres: return error(message='Could not place the new tile on the dashboard, a page refresh is needed') dataseries.update_default_options(tile) log.info('Created new tile report_id=%s dashboard_id=%s tile_id=%s', report_id, dashboard_id, tile.tile_id) tile_html = get_template_attribute('m.html', 'dashboard_tile')\ (tile.tile_id, mres.new_tiles[tile], moveresize) return success(result=dict( tile_html=tile_html, new_layout_id=mres.new_layout.layout_id, ))
def change_dashboard_ordering(): dashboard_id_list = request.get_json()['dashboard_id_list'] check_access(lambda: auth.access_profile()) dashboards.change_dashboards_ordering(auth.logged_owner_id(), dashboard_id_list) return success()
def profile_settings_preferences(): check_access(lambda: auth.access_profile()) if request.method == 'GET': api_key = users.select_api_key(auth.logged_owner_id()) or '' used_report_instances = reports.report_instance_count_for_owner(auth.logged_owner_id()) used_diskspace = reports.report_instance_diskspace_for_owner(auth.logged_owner_id()) selected_timezone = session['tz'] selected_dt_format = session.get('dt_format', ALL_DT_FORMATS[0][0]) user_row = User.select(auth.logged_owner_id()) return render_template('profile_settings_preferences.html', user_row=user_row, api_key=api_key, used_report_instances=used_report_instances, used_diskspace=used_diskspace, all_timezones=pytz.common_timezones, selected_timezone=selected_timezone, all_dt_formats=ALL_DT_FORMATS, selected_dt_format=selected_dt_format) stoken_check() user = User.select(auth.logged_owner_id()) d = {} timezone = request.form['timezone'] if timezone and timezone in pytz.common_timezones: d['chosen_timezone'] = timezone session['tz'] = timezone dt_format = request.form['dt_format'] if dt_format and dt_format in {x[0] for x in ALL_DT_FORMATS}: d['dt_format'] = dt_format session['dt_format'] = dt_format user.update_user_data(d) flash('Preferences updated') log.info('Updated user preferences with %s', d) return redirect(url_for('bp_mqe.profile_settings', settings_page='preferences'))
def render_recent_reports(): check_access(lambda: auth.access_profile()) report_list = reports.fetch_reports_by_name(auth.logged_owner_id(), limit=RECENT_REPORTS_LIMIT) report_names = [report.report_name for report in report_list] html = get_template_attribute('m.html', 'recent_reports')(report_names) return success(result=dict(html=html))
def reissue_api_key(): check_access(lambda: auth.access_profile()) stoken_check() users.assign_new_api_key(auth.logged_owner_id()) flash('New API key has been issued') return redirect(url_for('bp_mqe.profile_settings', settings_page='preferences'))
def delete_dashboard(): dashboard_id = request.get_json()['dashboard_id'] check_access(lambda: auth.access_dashboard(dashboard_id)) dashboard = dashboards.Dashboard.select(auth.logged_owner_id(), dashboard_id) if not dashboard: return error('No such dashboard') dashboard.delete() return success()
def autocomplete_report_name(): term = request.get_json()['term'] check_access(lambda: auth.access_profile()) report_list = reports.fetch_reports_by_name(auth.logged_owner_id(), term, None, AUTOCOMPLETE_REPORT_NAME_LIMIT) report_names = [report.report_name for report in report_list] return success(result=dict(data=report_names))
def report_instances_days(): report_name = request.get_json()['report_name'] tags = request.get_json().get('tags') check_access(lambda: auth.access_profile()) report = Report.select_by_name(auth.logged_owner_id(), report_name) days_dts = report.fetch_days(tags) days = [dt.strftime('%Y-%m-%d') for dt in days_dts] return success(result=dict(days=days))
def report_instance_for_viewer(): report_name = request.get_json()['report_name'] tags = request.get_json().get('tags') curr_report_instance_id = request.get_json()['curr_report_instance_id'] direction = request.get_json().get('direction') search_date = request.get_json().get('search_date') check_access(lambda: auth.access_profile()) report = Report.select_by_name(auth.logged_owner_id(), report_name) if not curr_report_instance_id: curr_report_instance_id = report.fetch_latest_instance_id(tags) if not curr_report_instance_id: return error() if not direction: if search_date is not None: ri = report.find_report_instance_by_dt(search_date, tags) else: ri = report.fetch_single_instance(curr_report_instance_id) elif direction == 'next': ri = report.fetch_next_instance(curr_report_instance_id, tags) elif direction == 'prev': ri = report.fetch_prev_instance(curr_report_instance_id, tags) else: return error('Wrong direction') res = {} res['report_id'] = report.report_id res['report_has_tags'] = report.has_tags() if ri: res['html_newest_table'] = get_template_attribute('m.html', 'table_as_html_table')(ri.table) res['created_raw'] = datetime_from_uuid1(ri.report_instance_id) res['created'] = format_datetime(datetime_from_uuid1(ri.report_instance_id)) res['tags'] = Markup(' '.join('<span class="selected-tag-name clickable">%s</span>' % tag for tag in ri.all_tags)) res['curr_report_instance_id'] = ri.report_instance_id res['has_next'] = report.fetch_next_instance(ri.report_instance_id, tags) is not None res['has_prev'] = report.fetch_prev_instance(ri.report_instance_id, tags) is not None else: res['html_newest_table'] = '' res['created_raw'] = '' res['created'] = '' res['tags'] = '' res['curr_report_instance_id'] = None res['has_next'] = False res['has_prev'] = False return success(result=res)
def add_dashboard(): name = request.get_json()['name'].strip() check_access(lambda: auth.access_profile()) if not name: return error('Empty name') for invalid_char in ('/', '\\'): if invalid_char in name: return error('Invalid character "%s"' % invalid_char) dbs = dashboards.OwnerDashboards(auth.logged_owner_id()) if name in {db.dashboard_name for db in dbs.dashboards}: return error('A dashboard with this name is already created') new_db = dbs.insert_dashboard(name, {}) html = get_template_attribute('m.html', 'db_tab')(new_db, False, True) return success(result=dict(html=html))
def fetch_move_tile_data(): dashboard_id = request.get_json()['dashboard_id'] tile_id = request.get_json()['tile_id'] check_access(lambda: auth.access_dashboard(dashboard_id)) dbs = dashboards.OwnerDashboards(auth.logged_owner_id()) options = [(serialize.mjson(db.dashboard_id), db.dashboard_name) for db in dbs.dashboards if db.dashboard_id != dashboard_id] tile = tiles.Tile.select(dashboard_id, tile_id) if not tile: return error('Invalid tile') result = dict( report_name=tile.report.report_name, has_options=bool(options), html_dashboard_select=get_template_attribute('m.html', 'select')('move-to-dashboard-select', options), ) return success(result=result)
def request_expire_tiles_without_data(): dashboard_id = request.get_json()['dashboard_id'] tile_id_list = request.get_json()['tile_id_list'] check_access(lambda: auth.access_dashboard(dashboard_id)) dashboard = dashboards.Dashboard.select(auth.logged_owner_id(), dashboard_id) if not dashboard: return error('No dashboard') max_seconds_without_data = nestedget(dashboard.dashboard_options, 'max_without_data', 'seconds_back') if not max_seconds_without_data: log.warn('request_expire_tiles_without_data called with empty max_seconds_without_data') return tile_list = tiles.Tile.select_multi(dashboard_id, tile_id_list).values() new_layout_id = tiles.expire_tiles_without_data(tile_list, max_seconds_without_data, None) return success(result=dict(tiles_expired=bool(new_layout_id)))
def set_layout(): dashboard_id = request.get_json()['dashboard_id'] layout_id = request.get_json()['layout_id'] data = request.get_json()['data'] master_tile_id_resized = request.get_json().get('master_tile_id_resized') check_access(lambda: auth.access_dashboard(dashboard_id)) new_layout = Layout(dict(data)) new_layout_id = new_layout.set(auth.logged_owner_id(), dashboard_id, layout_id) reload_required = False if new_layout_id and master_tile_id_resized: master_tile = tiles.Tile.select(dashboard_id, master_tile_id_resized) if master_tile: synced_layout_id = tpcreator.synchronize_sizes_of_tpcreated(master_tile, new_layout_id) reload_required = bool(synced_layout_id) return success(result=dict(new_layout_id=new_layout_id, reload_required=reload_required))
def add_report_name_entered(): report_name = request.get_json()['report_name'] check_access(lambda: auth.access_profile()) report = Report.select_by_name(auth.logged_owner_id(), report_name) if not report: return error(message='Incomplete report name') latest_instance_id = report.fetch_latest_instance_id() if not latest_instance_id: return error() ri = report.fetch_single_instance(latest_instance_id) tags = report.fetch_tags_sample('', TAGS_SAMPLE_LIMIT) res = {} res['has_tags'] = bool(tags) res['tag_sample'] = get_template_attribute('m.html', 'tag_sample')(tags) res['html_newest_table'] = get_template_attribute('m.html', 'table_as_html_table')(ri.table) res['report_id'] = report.report_id res['latest_instance_id'] = latest_instance_id res['latest_instance_tags'] = ri.all_tags return success(result=res)
def _report_list(filter_s, last_report_id): if not filter_s: filter_s = None if last_report_id: last_report_name = Report.select(last_report_id).report_name else: last_report_name = None report_list = reports.fetch_reports_by_name(auth.logged_owner_id(), filter_s, last_report_name, REPORTS_PER_PAGE) res = [{'report': report} for report in report_list] # fill latest_instance_dt for report_d in res: report_d['latest_instance_dt'] = None latest_instance_id = report_d['report'].fetch_latest_instance_id() if latest_instance_id: latest_ri = report_d['report'].fetch_single_instance(latest_instance_id) if latest_ri: report_d['latest_instance_dt'] = latest_ri.created return res
def update_dashboard(): dashboard_id = request.get_json()['dashboard_id'] new_dashboard_name = request.get_json()['new_dashboard_name'].strip() max_without_data = request.get_json().get('max_without_data') enable_synchronizing_tpcreated = request.get_json()['enable_synchronizing_tpcreated'] enable_synchronizing_tpcreated_x_axes = request.get_json()['enable_synchronizing_tpcreated_x_axes'] check_access(lambda: auth.access_dashboard(dashboard_id)) dashboard = dashboards.Dashboard.select(auth.logged_owner_id(), dashboard_id) if not dashboard: return error('Invalid dashboard') res = {} if dashboard.dashboard_name != new_dashboard_name: dashboard.update(dashboard_name=new_dashboard_name) res['new_dashboard_name'] = new_dashboard_name res['reloading_dashboard_required'] = \ dashboard.dashboard_options.get('enable_synchronizing_tpcreated', True) != \ enable_synchronizing_tpcreated or \ dashboard.dashboard_options.get('enable_synchronizing_tpcreated_x_axes', False) != \ enable_synchronizing_tpcreated_x_axes new_dashboard_options = copy.deepcopy(dashboard.dashboard_options) new_dashboard_options['max_without_data'] = max_without_data new_dashboard_options['enable_synchronizing_tpcreated'] = enable_synchronizing_tpcreated new_dashboard_options['enable_synchronizing_tpcreated_x_axes'] = \ enable_synchronizing_tpcreated_x_axes dashboard.update(dashboard_options=new_dashboard_options) res['new_dashboard_options'] = new_dashboard_options log.info('Updated dashboard %s with options %s', dashboard_id, new_dashboard_options) return success(result=res)
def api_key(): return users.select_api_key(auth.logged_owner_id()) or ''