diff --git a/spiffworkflow-backend/src/spiffworkflow_backend/models/active_user.py b/spiffworkflow-backend/src/spiffworkflow_backend/models/active_user.py index 71b81bc9..943edc6f 100644 --- a/spiffworkflow-backend/src/spiffworkflow_backend/models/active_user.py +++ b/spiffworkflow-backend/src/spiffworkflow_backend/models/active_user.py @@ -1,9 +1,10 @@ from __future__ import annotations -from spiffworkflow_backend.models.user import UserModel + from sqlalchemy import ForeignKey from spiffworkflow_backend.models.db import db from spiffworkflow_backend.models.db import SpiffworkflowBaseDBModel +from spiffworkflow_backend.models.user import UserModel class ActiveUserModel(SpiffworkflowBaseDBModel): diff --git a/spiffworkflow-backend/src/spiffworkflow_backend/routes/active_users_controller.py b/spiffworkflow-backend/src/spiffworkflow_backend/routes/active_users_controller.py index 5e9ba1ec..496d9b06 100644 --- a/spiffworkflow-backend/src/spiffworkflow_backend/routes/active_users_controller.py +++ b/spiffworkflow-backend/src/spiffworkflow_backend/routes/active_users_controller.py @@ -1,29 +1,22 @@ import json -import os import time -from spiffworkflow_backend.models.user import UserModel -from spiffworkflow_backend.models.db import db from typing import Generator -from flask import stream_with_context -import re -from typing import Any -from typing import Dict -from typing import Optional -from typing import Union -import connexion # type: ignore import flask.wrappers from flask import current_app from flask import g -from flask import jsonify -from flask import make_response +from flask import stream_with_context from flask.wrappers import Response + from spiffworkflow_backend.models.active_user import ActiveUserModel -from werkzeug.datastructures import FileStorage +from spiffworkflow_backend.models.db import db +from spiffworkflow_backend.models.user import UserModel def active_user_updates(last_visited_identifier: str) -> Response: - active_user = ActiveUserModel.query.filter_by(user_id=g.user.id, last_visited_identifier=last_visited_identifier).first() + active_user = ActiveUserModel.query.filter_by( + user_id=g.user.id, last_visited_identifier=last_visited_identifier + ).first() if active_user is None: active_user = ActiveUserModel(user_id=g.user.id, last_visited_identifier=last_visited_identifier) db.session.add(active_user) @@ -42,23 +35,23 @@ def _active_user_updates(last_visited_identifier: str, active_user: ActiveUserMo db.session.add(active_user) db.session.commit() - time.sleep(1) - cutoff_time_in_seconds = time.time() - 7 + cutoff_time_in_seconds = time.time() - 15 active_users = ( - UserModel.query - .join(ActiveUserModel) + UserModel.query.join(ActiveUserModel) .filter(ActiveUserModel.last_visited_identifier == last_visited_identifier) .filter(ActiveUserModel.last_seen_in_seconds > cutoff_time_in_seconds) - # .filter(UserModel.id != g.user.id) + .filter(UserModel.id != g.user.id) .all() ) yield f"data: {current_app.json.dumps(active_users)} \n\n" + time.sleep(5) -def active_user_unregister( - last_visited_identifier: str -) -> flask.wrappers.Response: - active_user = ActiveUserModel.query.filter_by(user_id=g.user.id, last_visited_identifier=last_visited_identifier).first() + +def active_user_unregister(last_visited_identifier: str) -> flask.wrappers.Response: + active_user = ActiveUserModel.query.filter_by( + user_id=g.user.id, last_visited_identifier=last_visited_identifier + ).first() if active_user is not None: db.session.delete(active_user) db.session.commit() diff --git a/spiffworkflow-backend/src/spiffworkflow_backend/routes/health_controller.py b/spiffworkflow-backend/src/spiffworkflow_backend/routes/health_controller.py index 556ec6b4..05408a4f 100644 --- a/spiffworkflow-backend/src/spiffworkflow_backend/routes/health_controller.py +++ b/spiffworkflow-backend/src/spiffworkflow_backend/routes/health_controller.py @@ -9,10 +9,6 @@ def status() -> Response: """Status.""" ProcessInstanceModel.query.filter().first() return make_response({"ok": True}, 200) -def status2() -> Response: - """Status.""" - ProcessInstanceModel.query.filter().first() - return make_response({"ok": True}, 200) def test_raise_error() -> Response: diff --git a/spiffworkflow-backend/src/spiffworkflow_backend/services/logging_service.py b/spiffworkflow-backend/src/spiffworkflow_backend/services/logging_service.py index d9732b0b..3a5ee845 100644 --- a/spiffworkflow-backend/src/spiffworkflow_backend/services/logging_service.py +++ b/spiffworkflow-backend/src/spiffworkflow_backend/services/logging_service.py @@ -130,6 +130,7 @@ def setup_logger(app: Flask) -> None: # these loggers have been deemed too verbose to be useful garbage_loggers_to_exclude = ["connexion", "flask_cors.extension"] + loggers_to_exclude_from_debug = ["sqlalchemy"] # make all loggers act the same for name in logging.root.manager.loggerDict: @@ -149,8 +150,17 @@ def setup_logger(app: Flask) -> None: for garbage_logger in garbage_loggers_to_exclude: if name.startswith(garbage_logger): exclude_logger_name_from_logging = True + + exclude_logger_name_from_debug = False + for logger_to_exclude_from_debug in loggers_to_exclude_from_debug: + if name.startswith(logger_to_exclude_from_debug): + exclude_logger_name_from_debug = True + if exclude_logger_name_from_debug: + the_logger.setLevel("INFO") + if not exclude_logger_name_from_logging: the_logger.addHandler(logging.StreamHandler(sys.stdout)) + for the_handler in the_logger.handlers: the_handler.setFormatter(log_formatter) the_handler.setLevel(log_level) diff --git a/spiffworkflow-frontend/src/components/ReactDiagramEditor.tsx b/spiffworkflow-frontend/src/components/ReactDiagramEditor.tsx index cddb7211..1855f955 100644 --- a/spiffworkflow-frontend/src/components/ReactDiagramEditor.tsx +++ b/spiffworkflow-frontend/src/components/ReactDiagramEditor.tsx @@ -88,6 +88,7 @@ type OwnProps = { onElementsChanged?: (..._args: any[]) => any; url?: string; callers?: ProcessModelCaller[]; + activeUserElement?: React.ReactElement; }; // https://codesandbox.io/s/quizzical-lake-szfyo?file=/src/App.js was a handy reference @@ -114,6 +115,7 @@ export default function ReactDiagramEditor({ onElementsChanged, url, callers, + activeUserElement, }: OwnProps) { const [diagramXMLString, setDiagramXMLString] = useState(''); const [diagramModelerState, setDiagramModelerState] = useState(null); @@ -672,6 +674,7 @@ export default function ReactDiagramEditor({ )} {getReferencesButton()} + {activeUserElement || null} ); } @@ -679,9 +682,9 @@ export default function ReactDiagramEditor({ }; return ( -