Skip to content

Commit

Permalink
Tracking instance install
Browse files Browse the repository at this point in the history
  • Loading branch information
mcanu committed Dec 26, 2024
1 parent 5eb3c26 commit 5e79486
Show file tree
Hide file tree
Showing 6 changed files with 105 additions and 35 deletions.
35 changes: 35 additions & 0 deletions label_studio/core/context_processors.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,13 @@
"""This file and its contents are licensed under the Apache License 2.0. Please see the included NOTICE for copyright information and LICENSE for a copy of the license.
"""
import os

from core.feature_flags import all_flags
from core.utils.common import collect_versions
from django.conf import settings as django_settings
from django.utils import timezone

from label_studio.core.utils.io import get_config_dir


def sentry_fe(request):
Expand Down Expand Up @@ -33,3 +38,33 @@ def settings(request):
feature_flags = all_flags(request.user)

return {'settings': django_settings, 'versions': versions, 'feature_flags': feature_flags}


def frontend_events(request):
events = []
if should_send_install_event():
events.append(
{
'name': 'setup.install',
'with_iframe': True,
}
)
return {'frontend_events': events}


_INSTALL_EVENT_SENT = False


def should_send_install_event():
# Only fire install event once per instance
global _INSTALL_EVENT_SENT
if django_settings.VERSION_EDITION == 'Community' and not _INSTALL_EVENT_SENT:
install_file = os.path.join(get_config_dir(), 'install.txt')
if not os.path.exists(install_file):
with open(install_file, 'w') as f:
f.write(timezone.now().isoformat())
_INSTALL_EVENT_SENT = True
return True
_INSTALL_EVENT_SENT = True

return False
1 change: 1 addition & 0 deletions label_studio/core/settings/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -316,6 +316,7 @@
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
'core.context_processors.settings',
'core.context_processors.frontend_events',
],
'builtins': ['django.templatetags.i18n'],
},
Expand Down
1 change: 1 addition & 0 deletions label_studio/templates/base.html
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,7 @@
feature_flags_default_value: {{ settings.FEATURE_FLAGS_DEFAULT_VALUE|json_dumps_ensure_ascii|safe }},
server_id: {{ request.server_id|json_dumps_ensure_ascii|safe }},
collect_analytics: {{ settings.COLLECT_ANALYTICS|yesno:"true,false" }},
frontend_events: {{ frontend_events|json_dumps_ensure_ascii|safe }},

{% block app_more_settings %}
flags: {
Expand Down
50 changes: 50 additions & 0 deletions label_studio/templates/simple.html
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
{% load static %}
{% load i18n %}
{% load filters %}

<!doctype html>
<html lang="en">
Expand Down Expand Up @@ -29,6 +30,55 @@
</head>

<body>
<script nonce="{{request.csp_nonce}}">
window.APP_SETTINGS = window.APP_SETTINGS ?? {};
window.APP_SETTINGS.collect_analytics = {{ settings.COLLECT_ANALYTICS|yesno:"true,false" }};

// Log event to the server, if analytics are enabled
// This is a fallback for when the __lsa global is not defined
// Normally this is a part of our main bundle but these pages do not use the main bundle
// and this allows us to log events from these pages
const logEvent = (eventName, metadata = {}) => {
if (!window.APP_SETTINGS?.collect_analytics) return;

const payload = {
...metadata,
event: eventName,
url: window.location.href,
};

window.requestIdleCallback(() => {
const params = new URLSearchParams({ __: JSON.stringify(payload) });
const url = `/__lsa/?${params}`;
try {
if (navigator.sendBeacon) {
navigator.sendBeacon(url);
} else {
const img = new Image();
img.src = url;
}
} catch {
// Ignore errors here
}
});
};
if (!window.__lsa) {
window.__lsa = logEvent;
}

const frontendEvents = {{ frontend_events|json_dumps_ensure_ascii|safe }};
frontendEvents.forEach((event) => {
if (window.APP_SETTINGS.collect_analytics && event.with_iframe) {
const iframe = document.createElement('iframe');
iframe.src = `https://www.labelstud.io/track/?event=${event.name}`;
iframe.style.display = 'none';
iframe.style.visibility = 'hidden';
document.body.appendChild(iframe);
}

__lsa(event.name);
});
</script>
{% block content %}
{% endblock %}

Expand Down
35 changes: 0 additions & 35 deletions label_studio/users/templates/users/new-ui/user_tips.html
Original file line number Diff line number Diff line change
Expand Up @@ -2,41 +2,6 @@

<script nonce="{{request.csp_nonce}}">

window.APP_SETTINGS = window.APP_SETTINGS ?? {};
window.APP_SETTINGS.collect_analytics = {{ settings.COLLECT_ANALYTICS|yesno:"true,false" }};

// Log event to the server, if analytics are enabled
// This is a fallback for when the __lsa global is not defined
// Normally this is a part of our main bundle but these pages do not use the main bundle
// and this allows us to log events from these pages
const logEvent = (eventName, metadata = {}) => {
if (!window.APP_SETTINGS?.collect_analytics) return;

const payload = {
...metadata,
event: eventName,
url: window.location.href,
};

window.requestIdleCallback(() => {
const params = new URLSearchParams({ __: JSON.stringify(payload) });
const url = `/__lsa/?${params}`;
try {
if (navigator.sendBeacon) {
navigator.sendBeacon(url);
} else {
const img = new Image();
img.src = url;
}
} catch {
// Ignore errors here
}
});
};
if (!window.__lsa) {
window.__lsa = logEvent;
}

const SERVER_ID = {{ request.server_id|json_dumps_ensure_ascii|safe }};
const EVENT_NAMESPACE_KEY = "heidi_tips";
const CACHE_KEY = "heidi_live_tips_collection";
Expand Down
18 changes: 18 additions & 0 deletions web/apps/labelstudio/src/app/RootPage.jsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,30 @@
import { Menubar } from "../components/Menubar/Menubar";
import { ProjectRoutes } from "../routes/ProjectRoutes";
import { useOrgValidation } from "../hooks/useOrgValidation";
import { useEffect } from "react";

export const RootPage = ({ content }) => {
useOrgValidation();
const pinned = localStorage.getItem("sidebar-pinned") === "true";
const opened = pinned && localStorage.getItem("sidebar-opened") === "true";

useEffect(() => {
const frontendEvents = window.APP_SETTINGS.frontend_events;

frontendEvents.forEach((event) => {
if (window.APP_SETTINGS.collect_analytics && event.with_iframe) {
const iframe = document.createElement("iframe");
iframe.src = `https://www.labelstud.io/track/?event=${event.name}`;
iframe.style.display = "none";
iframe.style.visibility = "hidden";
document.body.appendChild(iframe);
}

// TODO: __lsa(event.name)
// I don't know why but __lsa isn't defined yet here
});
}, []);

return (
<Menubar
enabled={true}
Expand Down

0 comments on commit 5e79486

Please sign in to comment.