fix: show recent visited dashboards and charts in recent_activity (#11481)

This commit is contained in:
Jesse Yang 2020-10-30 11:59:08 -07:00 committed by GitHub
parent fbcfaacda3
commit 29554a9f02
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -18,7 +18,7 @@
import logging import logging
import re import re
from contextlib import closing from contextlib import closing
from datetime import datetime from datetime import datetime, timedelta
from typing import Any, Callable, cast, Dict, List, Optional, Union from typing import Any, Callable, cast, Dict, List, Optional, Union
from urllib import parse from urllib import parse
@ -36,6 +36,7 @@ from sqlalchemy import and_, or_
from sqlalchemy.engine.url import make_url from sqlalchemy.engine.url import make_url
from sqlalchemy.exc import ArgumentError, DBAPIError, NoSuchModuleError, SQLAlchemyError from sqlalchemy.exc import ArgumentError, DBAPIError, NoSuchModuleError, SQLAlchemyError
from sqlalchemy.orm.session import Session from sqlalchemy.orm.session import Session
from sqlalchemy.sql import functions as func
from werkzeug.urls import Href from werkzeug.urls import Href
from superset import ( from superset import (
@ -1192,41 +1193,93 @@ class Superset(BaseSupersetView): # pylint: disable=too-many-public-methods
self, user_id: int self, user_id: int
) -> FlaskResponse: ) -> FlaskResponse:
"""Recent activity (actions) for a given user""" """Recent activity (actions) for a given user"""
if request.args.get("limit"): limit = request.args.get("limit")
limit = int(request.args["limit"]) limit = int(limit) if limit and limit.isdigit() else 100
else: actions = request.args.get("actions", "explore,dashboard").split(",")
limit = 1000 # whether to get distinct subjects
distinct = request.args.get("distinct") != "false"
qry = ( has_subject_title = or_(
db.session.query(Log, Dashboard, Slice) and_(
.outerjoin(Dashboard, Dashboard.id == Log.dashboard_id) Dashboard.dashboard_title is not None, Dashboard.dashboard_title != "",
.outerjoin(Slice, Slice.id == Log.slice_id) ),
.filter( and_(Slice.slice_name is not None, Slice.slice_name != ""),
and_(
Log.action.in_(("queries", "shortner", "sql_json")),
Log.user_id == user_id,
)
)
.order_by(Log.dttm.desc())
.limit(limit)
) )
if distinct:
one_year_ago = datetime.today() - timedelta(days=365)
subqry = (
db.session.query(
Log.dashboard_id,
Log.slice_id,
Log.action,
func.max(Log.dttm).label("dttm"),
)
.group_by(Log.dashboard_id, Log.slice_id, Log.action)
.filter(
and_(
Log.action.in_(actions),
Log.user_id == user_id,
# limit to one year of data to improve performance
Log.dttm > one_year_ago,
or_(Log.dashboard_id.isnot(None), Log.slice_id.isnot(None)),
)
)
.subquery()
)
qry = (
db.session.query(
subqry,
Dashboard.slug.label("dashboard_slug"),
Dashboard.dashboard_title,
Slice.slice_name,
)
.outerjoin(Dashboard, Dashboard.id == subqry.c.dashboard_id)
.outerjoin(Slice, Slice.id == subqry.c.slice_id,)
.filter(has_subject_title)
.order_by(subqry.c.dttm.desc())
.limit(limit)
)
else:
qry = (
db.session.query(
Log.dttm,
Log.action,
Log.dashboard_id,
Log.slice_id,
Dashboard.slug.label("dashboard_slug"),
Dashboard.dashboard_title,
Slice.slice_name,
)
.outerjoin(Dashboard, Dashboard.id == Log.dashboard_id)
.outerjoin(Slice, Slice.id == Log.slice_id)
.filter(has_subject_title)
.order_by(Log.dttm.desc())
.limit(limit)
)
payload = [] payload = []
for log in qry.all(): for log in qry.all():
item_url = None item_url = None
item_title = None item_title = None
if log.Dashboard: item_type = None
item_url = log.Dashboard.url if log.dashboard_id:
item_title = log.Dashboard.dashboard_title item_type = "dashboard"
elif log.Slice: item_url = Dashboard(id=log.dashboard_id, slug=log.dashboard_slug).url
item_url = log.Slice.slice_url item_title = log.dashboard_title
item_title = log.Slice.slice_name elif log.slice_id:
slc = Slice(id=log.slice_id, slice_name=log.slice_name)
item_type = "slice"
item_url = slc.slice_url
item_title = slc.chart
payload.append( payload.append(
{ {
"action": log.Log.action, "action": log.action,
"item_type": item_type,
"item_url": item_url, "item_url": item_url,
"item_title": item_title, "item_title": item_title,
"time": log.Log.dttm, "time": log.dttm,
} }
) )
return json_success(json.dumps(payload, default=utils.json_int_dttm_ser)) return json_success(json.dumps(payload, default=utils.json_int_dttm_ser))