diff --git a/api/chalicelib/core/click_maps.py b/api/chalicelib/core/click_maps.py index 0eed5bc6f..d115c420b 100644 --- a/api/chalicelib/core/click_maps.py +++ b/api/chalicelib/core/click_maps.py @@ -1,5 +1,5 @@ import schemas -from chalicelib.core import sessions_mobs, sessions as sessions_search +from chalicelib.core import sessions_mobs, sessions as sessions_search, events from chalicelib.utils import pg_client, helper SESSION_PROJECTION_COLS = """s.project_id, @@ -70,5 +70,7 @@ def search_short_session(data: schemas.FlatClickMapSessionsSearch, project_id, u if session: session['domURL'] = sessions_mobs.get_urls(session_id=session["session_id"], project_id=project_id) session['mobsUrl'] = sessions_mobs.get_urls_depercated(session_id=session["session_id"]) + session['events'] = events.get_by_sessionId2_pg(project_id=project_id, session_id=session["session_id"], + event_type=schemas.EventType.location) return helper.dict_to_camel_case(session) diff --git a/api/chalicelib/core/events.py b/api/chalicelib/core/events.py index e2c979799..1662fceee 100644 --- a/api/chalicelib/core/events.py +++ b/api/chalicelib/core/events.py @@ -1,3 +1,5 @@ +from typing import Optional + import schemas from chalicelib.core import issues from chalicelib.core import metadata @@ -53,44 +55,47 @@ def __get_grouped_clickrage(rows, session_id, project_id): return rows -def get_by_sessionId2_pg(session_id, project_id, group_clickrage=False): +def get_by_sessionId2_pg(session_id, project_id, group_clickrage=False, event_type: Optional[schemas.EventType] = None): with pg_client.PostgresClient() as cur: - cur.execute(cur.mogrify("""\ - SELECT - c.*, - 'CLICK' AS type - FROM events.clicks AS c - WHERE - c.session_id = %(session_id)s - ORDER BY c.timestamp;""", - {"project_id": project_id, "session_id": session_id}) - ) - rows = cur.fetchall() - if group_clickrage: - rows = __get_grouped_clickrage(rows=rows, session_id=session_id, project_id=project_id) - - cur.execute(cur.mogrify(""" - SELECT - i.*, - 'INPUT' AS type - FROM events.inputs AS i - WHERE - i.session_id = %(session_id)s - ORDER BY i.timestamp;""", - {"project_id": project_id, "session_id": session_id}) - ) - rows += cur.fetchall() - cur.execute(cur.mogrify("""\ - SELECT - l.*, - l.path AS value, - l.path AS url, - 'LOCATION' AS type - FROM events.pages AS l - WHERE - l.session_id = %(session_id)s - ORDER BY l.timestamp;""", {"project_id": project_id, "session_id": session_id})) - rows += cur.fetchall() + rows = [] + if event_type is None or event_type == schemas.EventType.click: + cur.execute(cur.mogrify("""\ + SELECT + c.*, + 'CLICK' AS type + FROM events.clicks AS c + WHERE + c.session_id = %(session_id)s + ORDER BY c.timestamp;""", + {"project_id": project_id, "session_id": session_id}) + ) + rows += cur.fetchall() + if group_clickrage: + rows = __get_grouped_clickrage(rows=rows, session_id=session_id, project_id=project_id) + if event_type is None or event_type == schemas.EventType.input: + cur.execute(cur.mogrify(""" + SELECT + i.*, + 'INPUT' AS type + FROM events.inputs AS i + WHERE + i.session_id = %(session_id)s + ORDER BY i.timestamp;""", + {"project_id": project_id, "session_id": session_id}) + ) + rows += cur.fetchall() + if event_type is None or event_type == schemas.EventType.location: + cur.execute(cur.mogrify("""\ + SELECT + l.*, + l.path AS value, + l.path AS url, + 'LOCATION' AS type + FROM events.pages AS l + WHERE + l.session_id = %(session_id)s + ORDER BY l.timestamp;""", {"project_id": project_id, "session_id": session_id})) + rows += cur.fetchall() rows = helper.list_to_camel_case(rows) rows = sorted(rows, key=lambda k: (k["timestamp"], k["messageId"])) return rows diff --git a/api/chalicelib/utils/s3.py b/api/chalicelib/utils/s3.py index 5aa0a0223..c2e5b58c7 100644 --- a/api/chalicelib/utils/s3.py +++ b/api/chalicelib/utils/s3.py @@ -1,12 +1,13 @@ import hashlib +from datetime import datetime, timedelta from urllib.parse import urlparse -from botocore.exceptions import ClientError -from decouple import config -from datetime import datetime, timedelta import boto3 import botocore from botocore.client import Config +from botocore.exceptions import ClientError +from decouple import config +from requests.models import PreparedRequest if not config("S3_HOST", default=False): client = boto3.client('s3') @@ -54,6 +55,20 @@ def get_presigned_url_for_sharing(bucket, expires_in, key, check_exists=False): ) +def get_presigned_url_for_upload_deprecated(bucket, expires_in, key, **args): + return client.generate_presigned_url( + 'put_object', + Params={ + 'Bucket': bucket, + 'Key': key + }, + ExpiresIn=expires_in + ) + + + + + def get_presigned_url_for_upload(bucket, expires_in, key, conditions=None, public=False, content_type=None): acl = 'private' if public: @@ -61,13 +76,16 @@ def get_presigned_url_for_upload(bucket, expires_in, key, conditions=None, publi fields = {"acl": acl} if content_type: fields["Content-Type"] = content_type - return client.generate_presigned_post( + url_parts = client.generate_presigned_post( Bucket=bucket, Key=key, ExpiresIn=expires_in, Fields=fields, Conditions=conditions, ) + req = PreparedRequest() + req.prepare_url(f"{url_parts['url']}/{url_parts['fields']['key']}", url_parts['fields']) + return req.url def get_file(source_bucket, source_key): diff --git a/api/routers/subs/metrics.py b/api/routers/subs/metrics.py index 4c0328751..dfa7acf86 100644 --- a/api/routers/subs/metrics.py +++ b/api/routers/subs/metrics.py @@ -1,3 +1,5 @@ +from typing import Union + from fastapi import Body, Depends import schemas @@ -152,7 +154,7 @@ def search_cards(projectId: int, data: schemas.SearchCardsSchema = Body(...), @app.get('/{projectId}/cards/{metric_id}', tags=["cards"]) @app.get('/{projectId}/metrics/{metric_id}', tags=["dashboard"]) @app.get('/{projectId}/custom_metrics/{metric_id}', tags=["customMetrics"]) -def get_card(projectId: int, metric_id: str, context: schemas.CurrentContext = Depends(OR_context)): +def get_card(projectId: int, metric_id: Union[int, str], context: schemas.CurrentContext = Depends(OR_context)): if not isinstance(metric_id, int): return {"errors": ["invalid card_id"]} data = custom_metrics.get_card(project_id=projectId, user_id=context.user_id, metric_id=metric_id) @@ -162,8 +164,10 @@ def get_card(projectId: int, metric_id: str, context: schemas.CurrentContext = D @app.get('/{projectId}/cards/{metric_id}/thumbnail', tags=["cards"]) -def sign_thumbnail_for_upload(projectId: int, metric_id: int, +def sign_thumbnail_for_upload(projectId: int, metric_id: Union[int, str], context: schemas.CurrentContext = Depends(OR_context)): + if not isinstance(metric_id, int): + return {"errors": ["invalid card_id"]} return custom_metrics.add_thumbnail(metric_id=metric_id, user_id=context.user_id, project_id=projectId)