Warning
This document is for an in-development version of Galaxy. You can alternatively view this page in the latest release if it exists or view the top of the latest release's documentation.
Source code for galaxy.webapps.reports.controllers.users
import calendar
import logging
import operator
from datetime import (
date,
datetime,
timedelta,
)
import sqlalchemy as sa
from markupsafe import escape
from sqlalchemy import (
false,
func,
select,
)
import galaxy.model
from galaxy import util
from galaxy.webapps.base.controller import (
BaseUIController,
web,
)
from galaxy.webapps.reports.controllers.jobs import sorter
from galaxy.webapps.reports.controllers.query import ReportQueryBuilder
log = logging.getLogger(__name__)
[docs]class Users(BaseUIController, ReportQueryBuilder):
[docs] @web.expose
def registered_users(self, trans, **kwd):
message = escape(util.restore_text(kwd.get("message", "")))
stmt = select(func.count(galaxy.model.User.id))
num_users = trans.sa_session.scalar(stmt)
return trans.fill_template("/webapps/reports/registered_users.mako", num_users=num_users, message=message)
[docs] @web.expose
def registered_users_per_month(self, trans, **kwd):
message = escape(util.restore_text(kwd.get("message", "")))
specs = sorter("date", kwd)
sort_id = specs.sort_id
order = specs.order
arrow = specs.arrow
q = (
sa.select(
self.select_month(galaxy.model.User.table.c.create_time).label("date"),
sa.func.count(galaxy.model.User.table.c.id).label("num_users"),
)
.group_by(self.group_by_month(galaxy.model.User.table.c.create_time))
.order_by(specs.exc_order)
)
users = []
for row in trans.sa_session.execute(q):
users.append((row.date.strftime("%Y-%m"), row.num_users, row.date.strftime("%B"), row.date.strftime("%Y")))
return trans.fill_template(
"/webapps/reports/registered_users_per_month.mako",
order=order,
arrow=arrow,
sort_id=sort_id,
users=users,
message=message,
)
[docs] @web.expose
def specified_month(self, trans, **kwd):
message = escape(util.restore_text(kwd.get("message", "")))
# If specified_date is not received, we'll default to the current month
specified_date = kwd.get("specified_date", datetime.utcnow().strftime("%Y-%m-%d"))
specified_month = specified_date[:7]
year, month = map(int, specified_month.split("-"))
start_date = date(year, month, 1)
end_date = start_date + timedelta(days=calendar.monthrange(year, month)[1])
month_label = start_date.strftime("%B")
year_label = start_date.strftime("%Y")
q = (
sa.select(
self.select_day(galaxy.model.User.table.c.create_time).label("date"),
sa.func.count(galaxy.model.User.table.c.id).label("num_users"),
)
.where(
sa.and_(
galaxy.model.User.table.c.create_time >= start_date,
galaxy.model.User.table.c.create_time < end_date,
)
)
.select_from(galaxy.model.User.table)
.group_by(self.group_by_day(galaxy.model.User.table.c.create_time))
.order_by(sa.desc("date"))
)
users = []
for row in trans.sa_session.execute(q):
users.append(
(row.date.strftime("%Y-%m-%d"), row.date.strftime("%d"), row.num_users, row.date.strftime("%A"))
)
return trans.fill_template(
"/webapps/reports/registered_users_specified_month.mako",
month_label=month_label,
year_label=year_label,
month=month,
users=users,
message=message,
)
[docs] @web.expose
def specified_date(self, trans, **kwd):
message = escape(util.restore_text(kwd.get("message", "")))
# If specified_date is not received, we'll default to the current month
specified_date = kwd.get("specified_date", datetime.utcnow().strftime("%Y-%m-%d"))
year, month, day = map(int, specified_date.split("-"))
start_date = date(year, month, day)
end_date = start_date + timedelta(days=1)
day_of_month = start_date.strftime("%d")
day_label = start_date.strftime("%A")
month_label = start_date.strftime("%B")
year_label = start_date.strftime("%Y")
q = (
sa.select(
self.select_day(galaxy.model.User.table.c.create_time).label("date"), galaxy.model.User.table.c.email
)
.where(
sa.and_(
galaxy.model.User.table.c.create_time >= start_date,
galaxy.model.User.table.c.create_time < end_date,
)
)
.select_from(galaxy.model.User.table)
.order_by(galaxy.model.User.table.c.email)
)
users = []
for row in trans.sa_session.execute(q):
users.append(row.email)
return trans.fill_template(
"/webapps/reports/registered_users_specified_date.mako",
specified_date=start_date,
day_label=day_label,
month_label=month_label,
year_label=year_label,
day_of_month=day_of_month,
users=users,
message=message,
)
[docs] @web.expose
def last_access_date(self, trans, **kwd):
message = escape(util.restore_text(kwd.get("message", "")))
specs = sorter("one", kwd)
sort_id = specs.sort_id
order = specs.order
arrow = specs.arrow
def name_to_num(name):
num = None
if name is not None and name.lower() == "zero":
num = 0
else:
num = 1
return num
if order == "desc":
_order = True
else:
_order = False
days_not_logged_in = kwd.get("days_not_logged_in", 90)
if not days_not_logged_in:
days_not_logged_in = 0
cutoff_time = datetime.utcnow() - timedelta(days=int(days_not_logged_in))
users = []
stmt = select(galaxy.model.User).filter(galaxy.model.User.deleted == false()).order_by(galaxy.model.User.email)
for user in trans.sa_session.scalars(stmt).all():
current_galaxy_session = user.current_galaxy_session
if current_galaxy_session:
last_galaxy_session = current_galaxy_session
if last_galaxy_session.update_time < cutoff_time:
users.append((user.email, last_galaxy_session.update_time.strftime("%Y-%m-%d")))
else:
# The user has never logged in
users.append((user.email, "never logged in"))
users = sorted(users, key=operator.itemgetter(name_to_num(sort_id)), reverse=_order)
return trans.fill_template(
"/webapps/reports/users_last_access_date.mako",
order=order,
arrow=arrow,
sort_id=sort_id,
days_not_logged_in=days_not_logged_in,
users=users,
message=message,
)
[docs] @web.expose
def user_disk_usage(self, trans, **kwd):
message = escape(util.restore_text(kwd.get("message", "")))
specs = sorter("disk_usage", kwd)
sort_id = specs.sort_id
order = specs.order
arrow = specs.arrow
if order == "desc":
_order = True
else:
_order = False
user_cutoff = int(kwd.get("user_cutoff", 60))
# disk_usage isn't indexed
all_users = trans.sa_session.scalars(select(galaxy.model.User)).all()
sort_attrgetter = operator.attrgetter(str(sort_id))
users = sorted(all_users, key=lambda x: sort_attrgetter(x) or 0, reverse=_order)
if user_cutoff:
users = users[:user_cutoff]
return trans.fill_template(
"/webapps/reports/users_user_disk_usage.mako",
order=order,
arrow=arrow,
sort_id=sort_id,
users=users,
user_cutoff=user_cutoff,
message=message,
)
[docs] @web.expose
def history_per_user(self, trans, **kwd):
message = escape(util.restore_text(kwd.get("message", "")))
user_cutoff = int(kwd.get("user_cutoff", 60))
sorting = 0 if kwd.get("sorting", "User") == "User" else 1
descending = 1 if kwd.get("descending", "desc") == "desc" else -1
reverse = descending == 1
sort_keys = (lambda v: v[0].lower(), lambda v: v[1])
req = (
sa.select(
sa.func.count(galaxy.model.History.table.c.id).label("history"),
galaxy.model.User.table.c.username.label("username"),
)
.select_from(sa.outerjoin(galaxy.model.History.table, galaxy.model.User.table))
.where(galaxy.model.History.table.c.user_id == galaxy.model.User.table.c.id)
.group_by("username")
.order_by(sa.desc("username"), "history")
)
histories = [
(_.username if _.username is not None else "Unknown", _.history) for _ in trans.sa_session.execute(req)
]
histories.sort(key=sort_keys[sorting], reverse=reverse)
if user_cutoff != 0:
histories = histories[:user_cutoff]
return trans.fill_template(
"/webapps/reports/history_per_user.mako",
histories=histories,
user_cutoff=user_cutoff,
sorting=sorting,
descending=descending,
message=message,
)