def get(self): """ Retrieve up to 20 queries modified in the last 7 days. Responds with a list of :ref:`query <query-response-label>` objects. """ if settings.FEATURE_DUMB_RECENTS: results = models.Query.by_user(self.current_user).order_by( models.Query.updated_at.desc()).limit(10) queries = [ q.to_dict(with_last_modified_by=False, with_user=False) for q in results ] else: queries = models.Query.recent(self.current_user.group_ids, self.current_user.id) recent = [ d.to_dict(with_last_modified_by=False, with_user=False) for d in queries ] global_recent = [] if len(recent) < 10: global_recent = [ d.to_dict(with_last_modified_by=False, with_user=False) for d in models.Query.recent(self.current_user.group_ids) ] queries = take( 20, distinct(chain(recent, global_recent), key=lambda d: d['id'])) return queries
def get(self): """ Lists dashboards modified in the last 7 days. """ if settings.FEATURE_DUMB_RECENTS: dashboards = models.Dashboard.all( self.current_org, self.current_user.group_ids, self.current_user.id).order_by( models.Dashboard.updated_at.desc()).limit(10) dashboards = [d.to_dict() for d in dashboards] else: recent = [ d.to_dict() for d in models.Dashboard.recent(self.current_org, self.current_user.group_ids, self.current_user.id, for_user=True) ] global_recent = [] if len(recent) < 10: global_recent = [ d.to_dict() for d in models.Dashboard.recent( self.current_org, self.current_user.group_ids, self.current_user.id) ] dashboards = take( 20, distinct(chain(recent, global_recent), key=lambda d: d['id'])) return dashboards
def handle(self, *args, **options): # django 1.6/1.7 takes cmd args as `args`, 1.8+ as `options` # sum their values to support both ways fields = distinct(list(args) + options.get('field', [])) groups = group_values(f.rsplit('.', 1) for f in fields) for model_name, field_names in groups.items(): self.migrate_fields(model_name, field_names)
def suggestions(): # Calling values() on a dict ensures we don't mess up the order target = { 'proteins': float(request.form['proteins']), 'carbs': float(request.form['carbs']), 'fats': float(request.form['fats']), }.values() size = int(request.form['combination_size']) tg_min = float(request.form['min_total_grams']) tg_max = float(request.form['max_total_grams']) ig_min = float(request.form['min_ingredient_grams']) ig_max = float(request.form['max_ingredient_grams']) error = float(request.form['cutoff_error']) ingredients = parse_ingredients(csv_file) if 'fixed_ingredient' in request.form: fixed_ingredient = find(lambda x: x.name==request.form['fixed_ingredient'], ingredients) compounds = np.array(list(fixed_ingredient.compounds)) target -= compounds * float(request.form['fixed_ingredient_grams']) if not all([x > 0 for x in target]): return jsonmsg("Fixed ingredients exceed food grams", 400) def valid_solution(sol): return sol is not None and within(tg_min, tg_max, sol['total'][0]) and sol['error'] < error def ingredients_names(sol): return tuple(sorted(map(lambda i: i[0], sol['ingredients']))) x = combinations(ingredients, size) x = imap(partial(calculate, target, ig_min, ig_max), x) x = ifilter(valid_solution, x) x = fn.distinct(x, key=ingredients_names) x = sorted(x, key=lambda x: x['error'], reverse=False) return jsonmsg(x, 200)
def get(self): recent = [d.to_dict() for d in models.Query.recent(current_user.id)] global_recent = [] if len(recent) < 10: global_recent = [d.to_dict() for d in models.Query.recent()] return distinct(chain(recent, global_recent), key=lambda d: d['id'])
def create_volume_string_set(paths): """ Returns uniq list of volume strings for a given list host paths """ f = funcy.rcompose( get_container_mount, lambda x: create_volume_string(x["host_dir"], x["container_dir"])) return list(funcy.distinct(map(f, paths)))
def get(self): recent = [d.to_dict() for d in models.Dashboard.recent(self.current_org, self.current_user.groups, self.current_user.id, for_user=True)] global_recent = [] if len(recent) < 10: global_recent = [d.to_dict() for d in models.Dashboard.recent(self.current_org, self.current_user.groups, self.current_user.id)] return take(20, distinct(chain(recent, global_recent), key=lambda d: d['id']))
def get_samples_columns(samples): preferred = [ 'id', 'description', 'characteristics_ch1', 'characteristics_ch2' ] exclude = ['attrs', 'supplementary_file', 'geo_accession'] columns = distinct(cat(s.keys() for s in samples)) return lift(preferred, lwithout(columns, *exclude))
def get(self): queries = models.Query.recent(self.current_user.groups, self.current_user.id) recent = [d.to_dict(with_last_modified_by=False) for d in queries] global_recent = [] if len(recent) < 10: global_recent = [d.to_dict(with_last_modified_by=False) for d in models.Query.recent(self.current_user.groups)] return take(20, distinct(chain(recent, global_recent), key=lambda d: d['id']))
def _collect_key_names(nodes): keys = [] for node in nodes._parse_tree: if isinstance(node, pystache.parser._EscapeNode): keys.append(node.key) elif isinstance(node, pystache.parser._SectionNode): keys.append(node.key) keys.extend(_collect_key_names(node.parsed)) return distinct(keys)
def _fleiss_kappa(sample_sets): all_samples_annos = cat(sample_sets) categories = distinct(sv.annotation or '' for sv in all_samples_annos) category_index = {c: i for i, c in enumerate(categories)} stats = defaultdict(lambda: [0] * len(categories)) for sv in all_samples_annos: stats[sv.sample_id][category_index[sv.annotation or '']] += 1 return fleiss_kappa(stats.values())
def _crash(cls, arbiter, space, data): for car in filter( lambda body: isinstance(body, Car), distinct( map( lambda body: body.car if hasattr(body, 'car') else body, map(lambda shape: shape.body, arbiter.shapes)))): car.crash_energy = min(car.crash_energy + arbiter.total_ke / 2, 10 * FPS * 100000)
def get(self): """ Lists dashboards modified in the last 7 days. """ recent = [d.to_dict() for d in models.Dashboard.recent(self.current_org, self.current_user.group_ids, self.current_user.id, for_user=True)] global_recent = [] if len(recent) < 10: global_recent = [d.to_dict() for d in models.Dashboard.recent(self.current_org, self.current_user.group_ids, self.current_user.id)] return take(20, distinct(chain(recent, global_recent), key=lambda d: d['id']))
def _catch(cls, arbiter, space, data): car = first( filter( lambda body: isinstance(body, Car), distinct( map( lambda body: body.car if hasattr(body, 'car') else body, map(lambda shape: shape.body, arbiter.shapes))))) if not car: return True car.score += 1 star = first( filter(lambda body: isinstance(body, Star), distinct(map(lambda shape: shape.body, arbiter.shapes)))) star.is_catched = True return False
def parse_union(registry: Any, model: Any, namespace: str) -> Schema: """Parse a python type hint union into an avro union. Note: due to how avro works with defaults, if None is part of a union, this method will force it to be the first item in the avro union, so that it can be used as a default. This is considered `best practices <https://avro.apache.org/docs/current/spec.html#Unions>_`. """ args = model.__args__ if type(None) in args: args = funcy.distinct([type(None), *args]) return AvroUnion( schemas=[parse(registry, schema, namespace) for schema in args])
def get(self): """ Retrieve up to 20 queries modified in the last 7 days. Responds with a list of :ref:`query <query-response-label>` objects. """ queries = models.Query.recent(self.current_user.group_ids, self.current_user.id) recent = [d.to_dict(with_last_modified_by=False) for d in queries] global_recent = [] if len(recent) < 10: global_recent = [d.to_dict(with_last_modified_by=False) for d in models.Query.recent(self.current_user.group_ids)] return take(20, distinct(chain(recent, global_recent), key=lambda d: d['id']))
def _cohens_kappa(annos1, annos2): assert set(s.sample_id for s in annos1) == set(s.sample_id for s in annos2) categories = distinct(sv.annotation or '' for sv in chain(annos1, annos2)) category_index = {c: i for i, c in enumerate(categories)} table = np.zeros((len(categories), len(categories))) annos1 = sorted(annos1, key=attrgetter('sample_id')) annos2 = sorted(annos2, key=attrgetter('sample_id')) for sv1, sv2 in zip(annos1, annos2): table[category_index[sv1.annotation or ''], category_index[sv2.annotation or '']] += 1 return cohens_kappa(table, return_results=False)
def get_vlan_users(ip, inf): def _get_users(child, i): rslt = do_some(child, 'show subscriber interface {i} | in external-vlan'.format(i=i)) vlans = re_all(r'external-vlan\s+:(\d+)', rslt) return vlans try: child = telnet(ip) rslt = do_some(child, 'show running-config | in smartgroup{inf}\.'.format(inf=inf)) infs = distinct(re_all(r'(smartgroup\S+)', rslt)) vlans = lmapcat(partial(_get_users, child), infs) close(child) vlans = count_by(int, vlans) except (pexpect.EOF, pexpect.TIMEOUT) as e: return ('fail', None, ip) return ('success', vlans, ip)
def get(self): """ Lists dashboards modified in the last 7 days. """ if settings.FEATURE_DUMB_RECENTS: dashboards = models.Dashboard.all(self.current_org, self.current_user.group_ids, self.current_user.id).order_by(models.Dashboard.updated_at.desc()).limit(10) dashboards = [d.to_dict() for d in dashboards] else: recent = [d.to_dict() for d in models.Dashboard.recent(self.current_org, self.current_user.group_ids, self.current_user.id, for_user=True)] global_recent = [] if len(recent) < 10: global_recent = [d.to_dict() for d in models.Dashboard.recent(self.current_org, self.current_user.group_ids, self.current_user.id)] dashboards = take(20, distinct(chain(recent, global_recent), key=lambda d: d['id'])) return dashboards
def get(self): """ Retrieve up to 20 queries modified in the last 7 days. Responds with a list of :ref:`query <query-response-label>` objects. """ queries = models.Query.recent(self.current_user.group_ids, self.current_user.id) recent = [d.to_dict(with_last_modified_by=False) for d in queries] global_recent = [] if len(recent) < 10: global_recent = [ d.to_dict(with_last_modified_by=False) for d in models.Query.recent(self.current_user.group_ids) ] return take( 20, distinct(chain(recent, global_recent), key=lambda d: d['id']))
def get(self): """ Retrieve up to 20 queries modified in the last 7 days. Responds with a list of :ref:`query <query-response-label>` objects. """ if settings.FEATURE_DUMB_RECENTS: results = models.Query.by_user(self.current_user).order_by(models.Query.updated_at.desc()).limit(10) queries = [q.to_dict(with_last_modified_by=False, with_user=False) for q in results] else: queries = models.Query.recent(self.current_user.group_ids, self.current_user.id) recent = [d.to_dict(with_last_modified_by=False, with_user=False) for d in queries] global_recent = [] if len(recent) < 10: global_recent = [d.to_dict(with_last_modified_by=False, with_user=False) for d in models.Query.recent(self.current_user.group_ids)] queries = take(20, distinct(chain(recent, global_recent), key=lambda d: d['id'])) return queries
def search(request): q = request.GET.get('q') if not q: return {'series': None} exclude_tags = keep(silent(int), request.GET.getlist('exclude_tags')) serie_tags, tag_series, tag_ids = series_tags_data() q_string, q_tags = _parse_query(q) q_tags, wrong_tags = split(lambda t: t.lower() in tag_ids, q_tags) if wrong_tags: message = 'Unknown tag%s %s.' % ('s' if len(wrong_tags) > 1 else '', ', '.join(wrong_tags)) messages.warning(request, message) if not q_string and not q_tags: return {'series': None} qs = search_series_qs(q_string) if q_tags: q_tag_ids = keep(tag_ids.get(t.lower()) for t in q_tags) include_series = reduce(set.intersection, (tag_series[t] for t in q_tag_ids)) if include_series: qs = qs.filter(id__in=include_series) else: message = 'No series annotated with %s.' \ % (q_tags[0] if len(q_tags) == 1 else 'all these tags simultaneously') messages.warning(request, message) return {'series': []} if exclude_tags: exclude_series = join(tag_series[t] for t in exclude_tags) qs = qs.exclude(id__in=exclude_series) series_ids = qs.values_list('id', flat=True) tags = distinct(imapcat(serie_tags, series_ids), key=itemgetter('id')) # TODO: do not hide excluded tags return { 'series': qs, 'tags': tags, 'serie_tags': serie_tags, }
def get(self): """ Lists dashboards modified in the last 7 days. """ recent = [ d.to_dict() for d in models.Dashboard.recent(self.current_org, self.current_user.group_ids, self.current_user.id, for_user=True) ] global_recent = [] if len(recent) < 10: global_recent = [ d.to_dict() for d in models.Dashboard.recent( self.current_org, self.current_user.group_ids, self.current_user.id) ] return take( 20, distinct(chain(recent, global_recent), key=lambda d: d['id']))
def get(self): """ Lists dashboards modified in the last 7 days. """ if settings.FEATURE_DUMB_RECENTS: dashboards = models.Dashboard.all( self.current_org, self.current_user.group_ids, self.current_user.id).order_by( models.Dashboard.updated_at.desc()).limit(10) dashboards = [d.to_dict() for d in dashboards] else: recent = [ d.to_dict() for d in models.Dashboard.recent(self.current_org, self.current_user.group_ids, self.current_user.id, for_user=True) ] # 获取该用户最近的dashboard global_recent = [] # 如果数量太少,就把全局的的dashboard也提取出来 if len(recent) < 10: global_recent = [ d.to_dict() for d in models.Dashboard.recent( self.current_org, self.current_user.group_ids, self.current_user.id) ] # chain 把一组可迭代对象连接成一个更大的迭代对象 # 把这两种dashboard合并在一起,然后最多取出前20个 dashboards = take( 20, distinct(chain(recent, global_recent), key=lambda d: d['id'])) return dashboards
'redash.query_runner.google_analytics', 'redash.query_runner.axibase_tsd', 'redash.query_runner.salesforce', 'redash.query_runner.query_results', 'redash.query_runner.prometheus', 'redash.query_runner.qubole', 'redash.query_runner.db2', 'redash.query_runner.druid', 'redash.query_runner.kylin' ] enabled_query_runners = array_from_string(os.environ.get("REDASH_ENABLED_QUERY_RUNNERS", ",".join(default_query_runners))) additional_query_runners = array_from_string(os.environ.get("REDASH_ADDITIONAL_QUERY_RUNNERS", "")) disabled_query_runners = array_from_string(os.environ.get("REDASH_DISABLED_QUERY_RUNNERS", "")) QUERY_RUNNERS = remove(set(disabled_query_runners), distinct(enabled_query_runners + additional_query_runners)) ADHOC_QUERY_TIME_LIMIT = int_or_none(os.environ.get('REDASH_ADHOC_QUERY_TIME_LIMIT', None)) # Destinations default_destinations = [ 'redash.destinations.email', 'redash.destinations.slack', 'redash.destinations.webhook', 'redash.destinations.hipchat', 'redash.destinations.mattermost', 'redash.destinations.chatwork', 'redash.destinations.pagerduty', ] enabled_destinations = array_from_string(os.environ.get("REDASH_ENABLED_DESTINATIONS", ",".join(default_destinations))) additional_destinations = array_from_string(os.environ.get("REDASH_ADDITIONAL_DESTINATIONS", ""))
'redash.query_runner.sqlite', 'redash.query_runner.dynamodb_sql', 'redash.query_runner.mssql', 'redash.query_runner.memsql_ds', 'redash.query_runner.jql', 'redash.query_runner.google_analytics', 'redash.query_runner.axibase_tsd', 'redash.query_runner.salesforce', 'redash.query_runner.drill' ] enabled_query_runners = array_from_string(os.environ.get("REDASH_ENABLED_QUERY_RUNNERS", ",".join(default_query_runners))) additional_query_runners = array_from_string(os.environ.get("REDASH_ADDITIONAL_QUERY_RUNNERS", "")) disabled_query_runners = array_from_string(os.environ.get("REDASH_DISABLED_QUERY_RUNNERS", "")) QUERY_RUNNERS = remove(set(disabled_query_runners), distinct(enabled_query_runners + additional_query_runners)) # Destinations default_destinations = [ 'redash.destinations.email', 'redash.destinations.slack', 'redash.destinations.webhook', 'redash.destinations.hipchat', ] enabled_destinations = array_from_string(os.environ.get("REDASH_ENABLED_DESTINATIONS", ",".join(default_destinations))) additional_destinations = array_from_string(os.environ.get("REDASH_ADDITIONAL_DESTINATIONS", "")) DESTINATIONS = distinct(enabled_destinations + additional_destinations) EVENT_REPORTING_WEBHOOKS = array_from_string(os.environ.get("REDASH_EVENT_REPORTING_WEBHOOKS", ""))
'redash.query_runner.mysql', 'redash.query_runner.pg', 'redash.query_runner.url', 'redash.query_runner.influx_db', 'redash.query_runner.elasticsearch', 'redash.query_runner.presto', 'redash.query_runner.hive_ds', 'redash.query_runner.impala_ds', 'redash.query_runner.vertica', 'redash.query_runner.treasuredata' ] enabled_query_runners = array_from_string(os.environ.get("REDASH_ENABLED_QUERY_RUNNERS", ",".join(default_query_runners))) additional_query_runners = array_from_string(os.environ.get("REDASH_ADDITIONAL_QUERY_RUNNERS", "")) QUERY_RUNNERS = distinct(enabled_query_runners + additional_query_runners) # Support for Sentry (http://getsentry.com/). Just set your Sentry DSN to enable it: SENTRY_DSN = os.environ.get("REDASH_SENTRY_DSN", "") # Client side toggles: ALLOW_SCRIPTS_IN_USER_INPUT = parse_boolean(os.environ.get("REDASH_ALLOW_SCRIPTS_IN_USER_INPUT", "false")) CLIENT_SIDE_METRICS = parse_boolean(os.environ.get("REDASH_CLIENT_SIDE_METRICS", "false")) # http://api.highcharts.com/highcharts#plotOptions.series.turboThreshold HIGHCHARTS_TURBO_THRESHOLD = int(os.environ.get("REDASH_HIGHCHARTS_TURBO_THRESHOLD", "1000")) DATE_FORMAT = os.environ.get("REDASH_DATE_FORMAT", "DD/MM/YY") # Features: FEATURE_ALLOW_ALL_TO_EDIT_QUERIES = parse_boolean(os.environ.get("REDASH_FEATURE_ALLOW_ALL_TO_EDIT", "true")) FEATURE_TABLES_PERMISSIONS = parse_boolean(os.environ.get("REDASH_FEATURE_TABLES_PERMISSIONS", "false"))
'redash.query_runner.elasticsearch', 'redash.query_runner.presto', 'redash.query_runner.hive_ds', 'redash.query_runner.impala_ds', 'redash.query_runner.vertica', 'redash.query_runner.treasuredata', 'redash.query_runner.sqlite', 'redash.query_runner.dynamodb_sql', 'redash.query_runner.mssql', ] enabled_query_runners = array_from_string(os.environ.get("REDASH_ENABLED_QUERY_RUNNERS", ",".join(default_query_runners))) additional_query_runners = array_from_string(os.environ.get("REDASH_ADDITIONAL_QUERY_RUNNERS", "")) disabled_query_runners = array_from_string(os.environ.get("REDASH_DISABLED_QUERY_RUNNERS", "")) QUERY_RUNNERS = remove(set(disabled_query_runners), distinct(enabled_query_runners + additional_query_runners)) EVENT_REPORTING_WEBHOOKS = array_from_string(os.environ.get("REDASH_EVENT_REPORTING_WEBHOOKS", "")) # Support for Sentry (http://getsentry.com/). Just set your Sentry DSN to enable it: SENTRY_DSN = os.environ.get("REDASH_SENTRY_DSN", "") # Client side toggles: ALLOW_SCRIPTS_IN_USER_INPUT = parse_boolean(os.environ.get("REDASH_ALLOW_SCRIPTS_IN_USER_INPUT", "false")) DATE_FORMAT = os.environ.get("REDASH_DATE_FORMAT", "DD/MM/YY") # Features: FEATURE_ALLOW_ALL_TO_EDIT_QUERIES = parse_boolean(os.environ.get("REDASH_FEATURE_ALLOW_ALL_TO_EDIT", "true")) FEATURE_TABLES_PERMISSIONS = parse_boolean(os.environ.get("REDASH_FEATURE_TABLES_PERMISSIONS", "false")) VERSION_CHECK = parse_boolean(os.environ.get("REDASH_VERSION_CEHCK", "true"))
'redash.query_runner.sqlite', 'redash.query_runner.dynamodb_sql', 'redash.query_runner.mssql', ] enabled_query_runners = array_from_string( os.environ.get("REDASH_ENABLED_QUERY_RUNNERS", ",".join(default_query_runners))) additional_query_runners = array_from_string( os.environ.get("REDASH_ADDITIONAL_QUERY_RUNNERS", "")) disabled_query_runners = array_from_string( os.environ.get("REDASH_DISABLED_QUERY_RUNNERS", "")) QUERY_RUNNERS = remove( set(disabled_query_runners), distinct(enabled_query_runners + additional_query_runners)) EVENT_REPORTING_WEBHOOKS = array_from_string( os.environ.get("REDASH_EVENT_REPORTING_WEBHOOKS", "")) # Support for Sentry (http://getsentry.com/). Just set your Sentry DSN to enable it: SENTRY_DSN = os.environ.get("REDASH_SENTRY_DSN", "") # Client side toggles: ALLOW_SCRIPTS_IN_USER_INPUT = parse_boolean( os.environ.get("REDASH_ALLOW_SCRIPTS_IN_USER_INPUT", "false")) DATE_FORMAT = os.environ.get("REDASH_DATE_FORMAT", "DD/MM/YY") # Features: FEATURE_ALLOW_ALL_TO_EDIT_QUERIES = parse_boolean( os.environ.get("REDASH_FEATURE_ALLOW_ALL_TO_EDIT", "true"))
'redash.query_runner.url', 'redash.query_runner.influx_db', 'redash.query_runner.elasticsearch', 'redash.query_runner.presto', 'redash.query_runner.hive_ds', 'redash.query_runner.impala_ds', 'redash.query_runner.vertica', 'redash.query_runner.treasuredata', 'redash.query_runner.oracle', 'redash.query_runner.sqlite', ] enabled_query_runners = array_from_string(os.environ.get("REDASH_ENABLED_QUERY_RUNNERS", ",".join(default_query_runners))) additional_query_runners = array_from_string(os.environ.get("REDASH_ADDITIONAL_QUERY_RUNNERS", "")) QUERY_RUNNERS = distinct(enabled_query_runners + additional_query_runners) # Support for Sentry (http://getsentry.com/). Just set your Sentry DSN to enable it: SENTRY_DSN = os.environ.get("REDASH_SENTRY_DSN", "") # Client side toggles: ALLOW_SCRIPTS_IN_USER_INPUT = parse_boolean(os.environ.get("REDASH_ALLOW_SCRIPTS_IN_USER_INPUT", "false")) CLIENT_SIDE_METRICS = parse_boolean(os.environ.get("REDASH_CLIENT_SIDE_METRICS", "false")) # http://api.highcharts.com/highcharts#plotOptions.series.turboThreshold HIGHCHARTS_TURBO_THRESHOLD = int(os.environ.get("REDASH_HIGHCHARTS_TURBO_THRESHOLD", "1000")) DATE_FORMAT = os.environ.get("REDASH_DATE_FORMAT", "DD/MM/YY") # Features: FEATURE_ALLOW_ALL_TO_EDIT_QUERIES = parse_boolean(os.environ.get("REDASH_FEATURE_ALLOW_ALL_TO_EDIT", "true")) FEATURE_TABLES_PERMISSIONS = parse_boolean(os.environ.get("REDASH_FEATURE_TABLES_PERMISSIONS", "false")) VERSION_CHECK = parse_boolean(os.environ.get("REDASH_VERSION_CEHCK", "true"))
"redash.query_runner.cloudwatch", "redash.query_runner.cloudwatch_insights", "redash.query_runner.neo4j", ] enabled_query_runners = array_from_string( os.environ.get("REDASH_ENABLED_QUERY_RUNNERS", ",".join(default_query_runners))) additional_query_runners = array_from_string( os.environ.get("REDASH_ADDITIONAL_QUERY_RUNNERS", "")) disabled_query_runners = array_from_string( os.environ.get("REDASH_DISABLED_QUERY_RUNNERS", "")) QUERY_RUNNERS = remove( set(disabled_query_runners), distinct(enabled_query_runners + additional_query_runners), ) dynamic_settings = importlib.import_module( os.environ.get("REDASH_DYNAMIC_SETTINGS_MODULE", "redash.settings.dynamic_settings")) # Destinations default_destinations = [ "redash.destinations.email", "redash.destinations.slack", "redash.destinations.webhook", "redash.destinations.hipchat", "redash.destinations.mattermost", "redash.destinations.chatwork", "redash.destinations.pagerduty",